From d1b9aa1e912185430aaf2d55f8c710a6964762df Mon Sep 17 00:00:00 2001 From: Arcadio Garcia Salvadores Date: Wed, 6 Jul 2022 21:00:43 -0700 Subject: [PATCH 01/44] CompositionCollectionView port and basic sample --- common/GlobalUsings_WinUI.cs | 92 +- common/Labs.MultiTarget.props | 5 - .../CompositionCollectionView.sln | 333 ++++ .../Expressions/CompositionExtensions.cs | 308 ++++ .../Expressions/ExpressionFunctions.cs | 1335 +++++++++++++++++ .../ExpressionNodes/BooleanNode.cs | 195 +++ .../Expressions/ExpressionNodes/ColorNode.cs | 138 ++ .../ExpressionNodes/ExpressionNode.cs | 720 +++++++++ .../ExpressionNodes/ExpressionNodeType.cs | 387 +++++ .../ExpressionNodes/Matrix3x2Node.cs | 393 +++++ .../Matrix4x4Node.Subchannel.cs | 99 ++ .../ExpressionNodes/Matrix4x4Node.cs | 488 ++++++ .../ExpressionNodes/QuaternionNode.cs | 198 +++ .../Expressions/ExpressionNodes/ScalarNode.cs | 385 +++++ .../ExpressionNodes/ValueKeywordKind.cs | 22 + .../ExpressionNodes/Vector2Node.cs | 370 +++++ .../ExpressionNodes/Vector3Node.cs | 404 +++++ .../ExpressionNodes/Vector4Node.cs | 418 ++++++ .../ExpressionValues.Constant.cs | 216 +++ .../ExpressionValues.CurrentValue.cs | 101 ++ .../ExpressionValues.Reference.cs | 140 ++ .../ExpressionValues.StartingValue.cs | 101 ++ .../ExpressionValues.Target.cs | 128 ++ .../Expressions/FloatExtensions.cs | 48 + .../Expressions/OperationType.cs | 47 + .../AmbientLightReferenceNode.cs | 46 + .../ReferenceNodes/ColorBrushReferenceNode.cs | 46 + .../DistantLightReferenceNode.cs | 55 + .../ReferenceNodes/DropShadowReferenceNode.cs | 73 + .../ReferenceNodes/InsetClipReferenceNode.cs | 136 ++ .../InteractionTrackerReferenceNode.cs | 154 ++ .../ManipulationPropertySetReferenceNode.cs | 79 + .../NineGridBrushReferenceNode.cs | 109 ++ .../ReferenceNodes/PointLightReferenceNode.cs | 91 ++ ...PointerPositionPropertySetReferenceNode.cs | 43 + .../PropertySetReferenceNode.cs | 52 + .../ReferenceNodes/ReferenceNode.cs | 168 +++ .../ReferenceNodes/SpotLightReferenceNode.cs | 145 ++ .../SurfaceBrushReferenceNode.cs | 154 ++ .../ReferenceNodes/VisualReferenceNode.cs | 162 ++ .../ExpressionsFork/ExpressionsFork.csproj | 183 +++ .../Properties/AssemblyInfo.cs | 29 + .../Properties/ExpressionsFork.rd.xml | 33 + .../BackedTemplatedControlSample.xaml | 17 + .../BackedTemplatedControlSample.xaml.cs | 24 + ...TemplatedControlWithCustomStyleSample.xaml | 27 + ...platedControlWithCustomStyleSample.xaml.cs | 24 + .../CompositionCollectionView.Sample.csproj | 31 + .../CompositionCollectionView.md | 32 + ...positionCollectionViewFirstSamplePage.xaml | 19 + ...itionCollectionViewFirstSamplePage.xaml.cs | 91 ++ .../TemplatedControlSample.xaml | 17 + .../TemplatedControlSample.xaml.cs | 24 + ...TemplatedControlWithCustomStyleSample.xaml | 28 + ...platedControlWithCustomStyleSample.xaml.cs | 24 + .../CompositionCollectionView.Uwp.csproj | 32 + .../Package.appxmanifest | 49 + .../Properties/AssemblyInfo.cs | 33 + .../Properties/Default.rd.xml | 31 + .../CompositionCollectionView.Wasm.csproj | 14 + .../CompositionCollectionView.Wasm/Program.cs | 19 + .../Properties/launchSettings.json | 27 + .../WasmCSS/Fonts.css | 27 + .../WasmScripts/AppManifest.js | 5 + .../wwwroot/web.config | 78 + ...CompositionCollectionView.WinAppSdk.csproj | 27 + .../Package.appxmanifest | 49 + .../Properties/launchSettings.json | 10 + .../app.manifest | 15 + .../src/AdditionalAssemblyInfo.cs | 13 + .../src/AnimatableCompositionNodeSet.cs | 97 ++ .../src/AnimatableScalarCompositionNode.cs | 65 + .../src/AnimatableVector3CompositionNode.cs | 64 + .../src/AnimationConstants.cs | 57 + .../ElementInteractionTrackerBehavior.cs | 47 + .../Behaviors/InteractionTrackerBehavior.cs | 195 +++ .../GesturePreviewControl.cs | 51 + .../InteractionTrackerGesture.cs | 146 ++ .../src/Behaviors/LayoutBehavior.cs | 26 + .../src/BindableCompositionPropertySet.cs | 123 ++ ...abs.WinUI.CompositionCollectionView.csproj | 65 + .../src/CompositionCollectionView.cs | 80 + .../src/CompositionCollectionView.projitems | 36 + .../src/CompositionCollectionView.shproj | 13 + ...ionCollectionViewStyle_ClassicBinding.xaml | 62 + .../CompositionCollectionViewStyle_xBind.xaml | 68 + ...mpositionCollectionViewStyle_xBind.xaml.cs | 20 + ...ompositionCollectionView_ClassicBinding.cs | 95 ++ .../src/CompositionCollectionView_xBind.cs | 71 + .../src/DeconstructPolyfillExtensions.cs | 20 + .../src/Dependencies.WinUI2.props | 20 + .../src/Dependencies.WinUI3.props | 20 + .../src/ElementReference.cs | 77 + .../src/GlobalUsings_Local.cs | 3 + .../src/IsExternalInit.cs | 13 + labs/CompositionCollectionView/src/Layout.cs | 547 +++++++ .../src/MathExtensions.cs | 10 + .../src/Themes/Generic.xaml | 25 + .../CompositionCollectionView.Tests.projitems | 14 + .../CompositionCollectionView.Tests.shproj | 13 + ...ampleCompositionCollectionViewTestClass.cs | 20 + ...ositionCollectionView.UnitTests.Uwp.csproj | 49 + .../Package.appxmanifest | 45 + .../Properties/AssemblyInfo.cs | 22 + .../Properties/Default.rd.xml | 29 + ...nCollectionView.UnitTests.WinAppSdk.csproj | 33 + .../Package.appxmanifest | 47 + .../Properties/launchSettings.json | 10 + .../app.manifest | 15 + 109 files changed, 11978 insertions(+), 51 deletions(-) create mode 100644 labs/CompositionCollectionView/CompositionCollectionView.sln create mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/CompositionExtensions.cs create mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionFunctions.cs create mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/BooleanNode.cs create mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/ColorNode.cs create mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/ExpressionNode.cs create mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/ExpressionNodeType.cs create mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Matrix3x2Node.cs create mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Matrix4x4Node.Subchannel.cs create mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Matrix4x4Node.cs create mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/QuaternionNode.cs create mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/ScalarNode.cs create mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/ValueKeywordKind.cs create mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Vector2Node.cs create mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Vector3Node.cs create mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Vector4Node.cs create mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionValues/ExpressionValues.Constant.cs create mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionValues/ExpressionValues.CurrentValue.cs create mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionValues/ExpressionValues.Reference.cs create mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionValues/ExpressionValues.StartingValue.cs create mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionValues/ExpressionValues.Target.cs create mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/FloatExtensions.cs create mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/OperationType.cs create mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/AmbientLightReferenceNode.cs create mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/ColorBrushReferenceNode.cs create mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/DistantLightReferenceNode.cs create mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/DropShadowReferenceNode.cs create mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/InsetClipReferenceNode.cs create mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/InteractionTrackerReferenceNode.cs create mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/ManipulationPropertySetReferenceNode.cs create mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/NineGridBrushReferenceNode.cs create mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/PointLightReferenceNode.cs create mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/PointerPositionPropertySetReferenceNode.cs create mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/PropertySetReferenceNode.cs create mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/ReferenceNode.cs create mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/SpotLightReferenceNode.cs create mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/SurfaceBrushReferenceNode.cs create mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/VisualReferenceNode.cs create mode 100644 labs/CompositionCollectionView/ExpressionsFork/ExpressionsFork.csproj create mode 100644 labs/CompositionCollectionView/ExpressionsFork/Properties/AssemblyInfo.cs create mode 100644 labs/CompositionCollectionView/ExpressionsFork/Properties/ExpressionsFork.rd.xml create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/BackedTemplatedControlSample.xaml create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/BackedTemplatedControlSample.xaml.cs create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/BackedTemplatedControlWithCustomStyleSample.xaml create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/BackedTemplatedControlWithCustomStyleSample.xaml.cs create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/CompositionCollectionView.Sample.csproj create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/CompositionCollectionView.md create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/CompositionCollectionViewFirstSamplePage.xaml create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/CompositionCollectionViewFirstSamplePage.xaml.cs create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/TemplatedControlSample.xaml create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/TemplatedControlSample.xaml.cs create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/TemplatedControlWithCustomStyleSample.xaml create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/TemplatedControlWithCustomStyleSample.xaml.cs create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Uwp/CompositionCollectionView.Uwp.csproj create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Uwp/Package.appxmanifest create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Uwp/Properties/AssemblyInfo.cs create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Uwp/Properties/Default.rd.xml create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/CompositionCollectionView.Wasm.csproj create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/Program.cs create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/Properties/launchSettings.json create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/WasmCSS/Fonts.css create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/WasmScripts/AppManifest.js create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/wwwroot/web.config create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.WinAppSdk/CompositionCollectionView.WinAppSdk.csproj create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.WinAppSdk/Package.appxmanifest create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.WinAppSdk/Properties/launchSettings.json create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.WinAppSdk/app.manifest create mode 100644 labs/CompositionCollectionView/src/AdditionalAssemblyInfo.cs create mode 100644 labs/CompositionCollectionView/src/AnimatableCompositionNodeSet.cs create mode 100644 labs/CompositionCollectionView/src/AnimatableScalarCompositionNode.cs create mode 100644 labs/CompositionCollectionView/src/AnimatableVector3CompositionNode.cs create mode 100644 labs/CompositionCollectionView/src/AnimationConstants.cs create mode 100644 labs/CompositionCollectionView/src/Behaviors/ElementInteractionTrackerBehavior.cs create mode 100644 labs/CompositionCollectionView/src/Behaviors/InteractionTrackerBehavior.cs create mode 100644 labs/CompositionCollectionView/src/Behaviors/InteractionTrackerGesture/GesturePreviewControl.cs create mode 100644 labs/CompositionCollectionView/src/Behaviors/InteractionTrackerGesture/InteractionTrackerGesture.cs create mode 100644 labs/CompositionCollectionView/src/Behaviors/LayoutBehavior.cs create mode 100644 labs/CompositionCollectionView/src/BindableCompositionPropertySet.cs create mode 100644 labs/CompositionCollectionView/src/CommunityToolkit.Labs.WinUI.CompositionCollectionView.csproj create mode 100644 labs/CompositionCollectionView/src/CompositionCollectionView.cs create mode 100644 labs/CompositionCollectionView/src/CompositionCollectionView.projitems create mode 100644 labs/CompositionCollectionView/src/CompositionCollectionView.shproj create mode 100644 labs/CompositionCollectionView/src/CompositionCollectionViewStyle_ClassicBinding.xaml create mode 100644 labs/CompositionCollectionView/src/CompositionCollectionViewStyle_xBind.xaml create mode 100644 labs/CompositionCollectionView/src/CompositionCollectionViewStyle_xBind.xaml.cs create mode 100644 labs/CompositionCollectionView/src/CompositionCollectionView_ClassicBinding.cs create mode 100644 labs/CompositionCollectionView/src/CompositionCollectionView_xBind.cs create mode 100644 labs/CompositionCollectionView/src/DeconstructPolyfillExtensions.cs create mode 100644 labs/CompositionCollectionView/src/Dependencies.WinUI2.props create mode 100644 labs/CompositionCollectionView/src/Dependencies.WinUI3.props create mode 100644 labs/CompositionCollectionView/src/ElementReference.cs create mode 100644 labs/CompositionCollectionView/src/GlobalUsings_Local.cs create mode 100644 labs/CompositionCollectionView/src/IsExternalInit.cs create mode 100644 labs/CompositionCollectionView/src/Layout.cs create mode 100644 labs/CompositionCollectionView/src/MathExtensions.cs create mode 100644 labs/CompositionCollectionView/src/Themes/Generic.xaml create mode 100644 labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/CompositionCollectionView.Tests.projitems create mode 100644 labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/CompositionCollectionView.Tests.shproj create mode 100644 labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/ExampleCompositionCollectionViewTestClass.cs create mode 100644 labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.Uwp/CompositionCollectionView.UnitTests.Uwp.csproj create mode 100644 labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.Uwp/Package.appxmanifest create mode 100644 labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.Uwp/Properties/AssemblyInfo.cs create mode 100644 labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.Uwp/Properties/Default.rd.xml create mode 100644 labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.WinAppSdk/CompositionCollectionView.UnitTests.WinAppSdk.csproj create mode 100644 labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.WinAppSdk/Package.appxmanifest create mode 100644 labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.WinAppSdk/Properties/launchSettings.json create mode 100644 labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.WinAppSdk/app.manifest diff --git a/common/GlobalUsings_WinUI.cs b/common/GlobalUsings_WinUI.cs index 0bfe14bd8..376fc837f 100644 --- a/common/GlobalUsings_WinUI.cs +++ b/common/GlobalUsings_WinUI.cs @@ -1,46 +1,46 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// This file contains directives available to projects that are compiled for multiple frameworks. -// Learn more global using directives at https://docs.microsoft.com/dotnet/csharp/language-reference/keywords/using-directive#global-modifier - -global using System.Runtime.InteropServices.WindowsRuntime; - -global using CommunityToolkit.Labs.WinUI; - -global using Windows.Foundation; -global using Windows.Foundation.Collections; - -#if !WINAPPSDK -global using Windows.ApplicationModel; -global using Windows.ApplicationModel.Activation; - -global using Windows.UI.Xaml.Automation; -global using Windows.UI.Xaml.Automation.Peers; - -global using Windows.UI.Xaml; -global using Windows.UI.Xaml.Controls; -global using Windows.UI.Xaml.Controls.Primitives; -global using Windows.UI.Xaml.Data; -global using Windows.UI.Xaml.Input; -global using Windows.UI.Xaml.Markup; -global using Windows.UI.Xaml.Media; -global using Windows.UI.Xaml.Navigation; - -#else - -global using Microsoft.UI.Xaml.Automation; -global using Microsoft.UI.Xaml.Automation.Peers; - -global using Microsoft.UI.Xaml; -global using Microsoft.UI.Xaml.Controls; -global using Microsoft.UI.Xaml.Controls.Primitives; -global using Microsoft.UI.Xaml.Data; -global using Microsoft.UI.Xaml.Input; -global using Microsoft.UI.Xaml.Markup; -global using Microsoft.UI.Xaml.Media; -global using Microsoft.UI.Xaml.Navigation; -#endif - -global using MUXC = Microsoft.UI.Xaml.Controls; +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// This file contains directives available to projects that are compiled for multiple frameworks. +// Learn more global using directives at https://docs.microsoft.com/dotnet/csharp/language-reference/keywords/using-directive#global-modifier + +global using System.Runtime.InteropServices.WindowsRuntime; + +global using CommunityToolkit.Labs.WinUI; + +global using Windows.Foundation; +global using Windows.Foundation.Collections; + +#if !WINAPPSDK +global using Windows.ApplicationModel; +global using Windows.ApplicationModel.Activation; + +global using Windows.UI.Xaml.Automation; +global using Windows.UI.Xaml.Automation.Peers; + +global using Windows.UI.Xaml; +global using Windows.UI.Xaml.Controls; +global using Windows.UI.Xaml.Controls.Primitives; +global using Windows.UI.Xaml.Data; +global using Windows.UI.Xaml.Input; +global using Windows.UI.Xaml.Markup; +global using Windows.UI.Xaml.Media; +global using Windows.UI.Xaml.Navigation; + +#else + +global using Microsoft.UI.Xaml.Automation; +global using Microsoft.UI.Xaml.Automation.Peers; + +global using Microsoft.UI.Xaml; +global using Microsoft.UI.Xaml.Controls; +global using Microsoft.UI.Xaml.Controls.Primitives; +global using Microsoft.UI.Xaml.Data; +global using Microsoft.UI.Xaml.Input; +global using Microsoft.UI.Xaml.Markup; +global using Microsoft.UI.Xaml.Media; +global using Microsoft.UI.Xaml.Navigation; +#endif + +global using MUXC = Microsoft.UI.Xaml.Controls; diff --git a/common/Labs.MultiTarget.props b/common/Labs.MultiTarget.props index 52913e658..3b15b4721 100644 --- a/common/Labs.MultiTarget.props +++ b/common/Labs.MultiTarget.props @@ -10,12 +10,7 @@ and use the value directly. --> - $(NetStandardCommonTargetFramework); $(UwpTargetFramework); - $(WinAppSdkTargetFramework); - $(MacOSLibTargetFramework); - $(iOSLibTargetFramework); - $(AndroidLibTargetFramework); true diff --git a/labs/CompositionCollectionView/CompositionCollectionView.sln b/labs/CompositionCollectionView/CompositionCollectionView.sln new file mode 100644 index 000000000..1afdbf831 --- /dev/null +++ b/labs/CompositionCollectionView/CompositionCollectionView.sln @@ -0,0 +1,333 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31919.166 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CommunityToolkit.Labs.WinUI.CompositionCollectionView", "src\CommunityToolkit.Labs.WinUI.CompositionCollectionView.csproj", "{30FD6398-9706-434D-8A23-088E2AAEDD11}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CompositionCollectionView.Uwp", "samples\CompositionCollectionView.Uwp\CompositionCollectionView.Uwp.csproj", "{052083DA-908D-40A3-AD89-DCD26450A34C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompositionCollectionView.Wasm", "samples\CompositionCollectionView.Wasm\CompositionCollectionView.Wasm.csproj", "{FC69D0DF-E3E3-4135-BA9A-CBAA7C9025A7}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompositionCollectionView.Sample", "samples\CompositionCollectionView.Sample\CompositionCollectionView.Sample.csproj", "{B521DDDD-EC8E-4BF8-B15F-AAD7E430A5CB}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Platforms", "Platforms", "{25CC39A7-DB18-4A15-8E4A-5E0B1FF20DDE}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompositionCollectionView.WinAppSdk", "samples\CompositionCollectionView.WinAppSdk\CompositionCollectionView.WinAppSdk.csproj", "{4F4E8EC4-C15D-42FC-8ADE-96F5F97F9C55}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CommunityToolkit.Labs.Core.SourceGenerators", "..\..\common\CommunityToolkit.Labs.Core.SourceGenerators\CommunityToolkit.Labs.Core.SourceGenerators.csproj", "{66E6DA8A-FEFC-4221-A476-4314A4D692F6}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CommunityToolkit.Labs.Core.SourceGenerators.XamlNamedPropertyRelay", "..\..\common\CommunityToolkit.Labs.Core.SourceGenerators.XamlNamedPropertyRelay\CommunityToolkit.Labs.Core.SourceGenerators.XamlNamedPropertyRelay.csproj", "{7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{4CB70587-B61D-4C18-B831-E8B31EA714C5}" +EndProject +Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "CompositionCollectionView.Tests", "tests\CompositionCollectionView.Tests\CompositionCollectionView.Tests.shproj", "{69B7E819-DCF5-48F5-93DA-5191416A1270}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompositionCollectionView.UnitTests.WinAppSdk", "tests\CompositionCollectionView.UnitTests.WinAppSdk\CompositionCollectionView.UnitTests.WinAppSdk.csproj", "{67FA8BC7-0C0D-4557-808B-BCE056C259CA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CompositionCollectionView.UnitTests.Uwp", "tests\CompositionCollectionView.UnitTests.Uwp\CompositionCollectionView.UnitTests.Uwp.csproj", "{87F8E99E-6C8A-43BA-9FAC-F8FE49347FC2}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Labs Dependencies", "Labs Dependencies", "{326F9C50-2898-4589-8D40-25E9283F0D5A}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CommunityToolkit.Labs.Core.SourceGenerators.LabsUITestMethod", "..\..\common\CommunityToolkit.Labs.Core.SourceGenerators.LabsUITestMethod\CommunityToolkit.Labs.Core.SourceGenerators.LabsUITestMethod.csproj", "{79F79471-9947-45F5-81FE-4EBE2B8D0B1D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExpressionsFork", "ExpressionsFork\ExpressionsFork.csproj", "{1E97AC9F-CB43-4B98-AEF9-2BA035E037A7}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|ARM = Debug|ARM + Debug|ARM64 = Debug|ARM64 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|ARM = Release|ARM + Release|ARM64 = Release|ARM64 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {30FD6398-9706-434D-8A23-088E2AAEDD11}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {30FD6398-9706-434D-8A23-088E2AAEDD11}.Debug|Any CPU.Build.0 = Debug|Any CPU + {30FD6398-9706-434D-8A23-088E2AAEDD11}.Debug|ARM.ActiveCfg = Debug|Any CPU + {30FD6398-9706-434D-8A23-088E2AAEDD11}.Debug|ARM.Build.0 = Debug|Any CPU + {30FD6398-9706-434D-8A23-088E2AAEDD11}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {30FD6398-9706-434D-8A23-088E2AAEDD11}.Debug|ARM64.Build.0 = Debug|Any CPU + {30FD6398-9706-434D-8A23-088E2AAEDD11}.Debug|x64.ActiveCfg = Debug|Any CPU + {30FD6398-9706-434D-8A23-088E2AAEDD11}.Debug|x64.Build.0 = Debug|Any CPU + {30FD6398-9706-434D-8A23-088E2AAEDD11}.Debug|x86.ActiveCfg = Debug|Any CPU + {30FD6398-9706-434D-8A23-088E2AAEDD11}.Debug|x86.Build.0 = Debug|Any CPU + {30FD6398-9706-434D-8A23-088E2AAEDD11}.Release|Any CPU.ActiveCfg = Release|Any CPU + {30FD6398-9706-434D-8A23-088E2AAEDD11}.Release|Any CPU.Build.0 = Release|Any CPU + {30FD6398-9706-434D-8A23-088E2AAEDD11}.Release|ARM.ActiveCfg = Release|Any CPU + {30FD6398-9706-434D-8A23-088E2AAEDD11}.Release|ARM.Build.0 = Release|Any CPU + {30FD6398-9706-434D-8A23-088E2AAEDD11}.Release|ARM64.ActiveCfg = Release|Any CPU + {30FD6398-9706-434D-8A23-088E2AAEDD11}.Release|ARM64.Build.0 = Release|Any CPU + {30FD6398-9706-434D-8A23-088E2AAEDD11}.Release|x64.ActiveCfg = Release|Any CPU + {30FD6398-9706-434D-8A23-088E2AAEDD11}.Release|x64.Build.0 = Release|Any CPU + {30FD6398-9706-434D-8A23-088E2AAEDD11}.Release|x86.ActiveCfg = Release|Any CPU + {30FD6398-9706-434D-8A23-088E2AAEDD11}.Release|x86.Build.0 = Release|Any CPU + {052083DA-908D-40A3-AD89-DCD26450A34C}.Debug|Any CPU.ActiveCfg = Debug|x64 + {052083DA-908D-40A3-AD89-DCD26450A34C}.Debug|Any CPU.Build.0 = Debug|x64 + {052083DA-908D-40A3-AD89-DCD26450A34C}.Debug|Any CPU.Deploy.0 = Debug|x64 + {052083DA-908D-40A3-AD89-DCD26450A34C}.Debug|ARM.ActiveCfg = Debug|ARM + {052083DA-908D-40A3-AD89-DCD26450A34C}.Debug|ARM.Build.0 = Debug|ARM + {052083DA-908D-40A3-AD89-DCD26450A34C}.Debug|ARM.Deploy.0 = Debug|ARM + {052083DA-908D-40A3-AD89-DCD26450A34C}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {052083DA-908D-40A3-AD89-DCD26450A34C}.Debug|ARM64.Build.0 = Debug|ARM64 + {052083DA-908D-40A3-AD89-DCD26450A34C}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {052083DA-908D-40A3-AD89-DCD26450A34C}.Debug|x64.ActiveCfg = Debug|x64 + {052083DA-908D-40A3-AD89-DCD26450A34C}.Debug|x64.Build.0 = Debug|x64 + {052083DA-908D-40A3-AD89-DCD26450A34C}.Debug|x64.Deploy.0 = Debug|x64 + {052083DA-908D-40A3-AD89-DCD26450A34C}.Debug|x86.ActiveCfg = Debug|x86 + {052083DA-908D-40A3-AD89-DCD26450A34C}.Debug|x86.Build.0 = Debug|x86 + {052083DA-908D-40A3-AD89-DCD26450A34C}.Debug|x86.Deploy.0 = Debug|x86 + {052083DA-908D-40A3-AD89-DCD26450A34C}.Release|Any CPU.ActiveCfg = Release|x64 + {052083DA-908D-40A3-AD89-DCD26450A34C}.Release|Any CPU.Build.0 = Release|x64 + {052083DA-908D-40A3-AD89-DCD26450A34C}.Release|Any CPU.Deploy.0 = Release|x64 + {052083DA-908D-40A3-AD89-DCD26450A34C}.Release|ARM.ActiveCfg = Release|ARM + {052083DA-908D-40A3-AD89-DCD26450A34C}.Release|ARM.Build.0 = Release|ARM + {052083DA-908D-40A3-AD89-DCD26450A34C}.Release|ARM.Deploy.0 = Release|ARM + {052083DA-908D-40A3-AD89-DCD26450A34C}.Release|ARM64.ActiveCfg = Release|ARM64 + {052083DA-908D-40A3-AD89-DCD26450A34C}.Release|ARM64.Build.0 = Release|ARM64 + {052083DA-908D-40A3-AD89-DCD26450A34C}.Release|ARM64.Deploy.0 = Release|ARM64 + {052083DA-908D-40A3-AD89-DCD26450A34C}.Release|x64.ActiveCfg = Release|x64 + {052083DA-908D-40A3-AD89-DCD26450A34C}.Release|x64.Build.0 = Release|x64 + {052083DA-908D-40A3-AD89-DCD26450A34C}.Release|x64.Deploy.0 = Release|x64 + {052083DA-908D-40A3-AD89-DCD26450A34C}.Release|x86.ActiveCfg = Release|x86 + {052083DA-908D-40A3-AD89-DCD26450A34C}.Release|x86.Build.0 = Release|x86 + {052083DA-908D-40A3-AD89-DCD26450A34C}.Release|x86.Deploy.0 = Release|x86 + {FC69D0DF-E3E3-4135-BA9A-CBAA7C9025A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FC69D0DF-E3E3-4135-BA9A-CBAA7C9025A7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FC69D0DF-E3E3-4135-BA9A-CBAA7C9025A7}.Debug|ARM.ActiveCfg = Debug|Any CPU + {FC69D0DF-E3E3-4135-BA9A-CBAA7C9025A7}.Debug|ARM.Build.0 = Debug|Any CPU + {FC69D0DF-E3E3-4135-BA9A-CBAA7C9025A7}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {FC69D0DF-E3E3-4135-BA9A-CBAA7C9025A7}.Debug|ARM64.Build.0 = Debug|Any CPU + {FC69D0DF-E3E3-4135-BA9A-CBAA7C9025A7}.Debug|x64.ActiveCfg = Debug|Any CPU + {FC69D0DF-E3E3-4135-BA9A-CBAA7C9025A7}.Debug|x64.Build.0 = Debug|Any CPU + {FC69D0DF-E3E3-4135-BA9A-CBAA7C9025A7}.Debug|x86.ActiveCfg = Debug|Any CPU + {FC69D0DF-E3E3-4135-BA9A-CBAA7C9025A7}.Debug|x86.Build.0 = Debug|Any CPU + {FC69D0DF-E3E3-4135-BA9A-CBAA7C9025A7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FC69D0DF-E3E3-4135-BA9A-CBAA7C9025A7}.Release|Any CPU.Build.0 = Release|Any CPU + {FC69D0DF-E3E3-4135-BA9A-CBAA7C9025A7}.Release|ARM.ActiveCfg = Release|Any CPU + {FC69D0DF-E3E3-4135-BA9A-CBAA7C9025A7}.Release|ARM.Build.0 = Release|Any CPU + {FC69D0DF-E3E3-4135-BA9A-CBAA7C9025A7}.Release|ARM64.ActiveCfg = Release|Any CPU + {FC69D0DF-E3E3-4135-BA9A-CBAA7C9025A7}.Release|ARM64.Build.0 = Release|Any CPU + {FC69D0DF-E3E3-4135-BA9A-CBAA7C9025A7}.Release|x64.ActiveCfg = Release|Any CPU + {FC69D0DF-E3E3-4135-BA9A-CBAA7C9025A7}.Release|x64.Build.0 = Release|Any CPU + {FC69D0DF-E3E3-4135-BA9A-CBAA7C9025A7}.Release|x86.ActiveCfg = Release|Any CPU + {FC69D0DF-E3E3-4135-BA9A-CBAA7C9025A7}.Release|x86.Build.0 = Release|Any CPU + {B521DDDD-EC8E-4BF8-B15F-AAD7E430A5CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B521DDDD-EC8E-4BF8-B15F-AAD7E430A5CB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B521DDDD-EC8E-4BF8-B15F-AAD7E430A5CB}.Debug|ARM.ActiveCfg = Debug|Any CPU + {B521DDDD-EC8E-4BF8-B15F-AAD7E430A5CB}.Debug|ARM.Build.0 = Debug|Any CPU + {B521DDDD-EC8E-4BF8-B15F-AAD7E430A5CB}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {B521DDDD-EC8E-4BF8-B15F-AAD7E430A5CB}.Debug|ARM64.Build.0 = Debug|Any CPU + {B521DDDD-EC8E-4BF8-B15F-AAD7E430A5CB}.Debug|x64.ActiveCfg = Debug|Any CPU + {B521DDDD-EC8E-4BF8-B15F-AAD7E430A5CB}.Debug|x64.Build.0 = Debug|Any CPU + {B521DDDD-EC8E-4BF8-B15F-AAD7E430A5CB}.Debug|x86.ActiveCfg = Debug|Any CPU + {B521DDDD-EC8E-4BF8-B15F-AAD7E430A5CB}.Debug|x86.Build.0 = Debug|Any CPU + {B521DDDD-EC8E-4BF8-B15F-AAD7E430A5CB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B521DDDD-EC8E-4BF8-B15F-AAD7E430A5CB}.Release|Any CPU.Build.0 = Release|Any CPU + {B521DDDD-EC8E-4BF8-B15F-AAD7E430A5CB}.Release|ARM.ActiveCfg = Release|Any CPU + {B521DDDD-EC8E-4BF8-B15F-AAD7E430A5CB}.Release|ARM.Build.0 = Release|Any CPU + {B521DDDD-EC8E-4BF8-B15F-AAD7E430A5CB}.Release|ARM64.ActiveCfg = Release|Any CPU + {B521DDDD-EC8E-4BF8-B15F-AAD7E430A5CB}.Release|ARM64.Build.0 = Release|Any CPU + {B521DDDD-EC8E-4BF8-B15F-AAD7E430A5CB}.Release|x64.ActiveCfg = Release|Any CPU + {B521DDDD-EC8E-4BF8-B15F-AAD7E430A5CB}.Release|x64.Build.0 = Release|Any CPU + {B521DDDD-EC8E-4BF8-B15F-AAD7E430A5CB}.Release|x86.ActiveCfg = Release|Any CPU + {B521DDDD-EC8E-4BF8-B15F-AAD7E430A5CB}.Release|x86.Build.0 = Release|Any CPU + {4F4E8EC4-C15D-42FC-8ADE-96F5F97F9C55}.Debug|Any CPU.ActiveCfg = Debug|x64 + {4F4E8EC4-C15D-42FC-8ADE-96F5F97F9C55}.Debug|Any CPU.Build.0 = Debug|x64 + {4F4E8EC4-C15D-42FC-8ADE-96F5F97F9C55}.Debug|Any CPU.Deploy.0 = Debug|x64 + {4F4E8EC4-C15D-42FC-8ADE-96F5F97F9C55}.Debug|ARM.ActiveCfg = Debug|x64 + {4F4E8EC4-C15D-42FC-8ADE-96F5F97F9C55}.Debug|ARM.Build.0 = Debug|x64 + {4F4E8EC4-C15D-42FC-8ADE-96F5F97F9C55}.Debug|ARM.Deploy.0 = Debug|x64 + {4F4E8EC4-C15D-42FC-8ADE-96F5F97F9C55}.Debug|ARM64.ActiveCfg = Debug|arm64 + {4F4E8EC4-C15D-42FC-8ADE-96F5F97F9C55}.Debug|ARM64.Build.0 = Debug|arm64 + {4F4E8EC4-C15D-42FC-8ADE-96F5F97F9C55}.Debug|ARM64.Deploy.0 = Debug|arm64 + {4F4E8EC4-C15D-42FC-8ADE-96F5F97F9C55}.Debug|x64.ActiveCfg = Debug|x64 + {4F4E8EC4-C15D-42FC-8ADE-96F5F97F9C55}.Debug|x64.Build.0 = Debug|x64 + {4F4E8EC4-C15D-42FC-8ADE-96F5F97F9C55}.Debug|x64.Deploy.0 = Debug|x64 + {4F4E8EC4-C15D-42FC-8ADE-96F5F97F9C55}.Debug|x86.ActiveCfg = Debug|x86 + {4F4E8EC4-C15D-42FC-8ADE-96F5F97F9C55}.Debug|x86.Build.0 = Debug|x86 + {4F4E8EC4-C15D-42FC-8ADE-96F5F97F9C55}.Debug|x86.Deploy.0 = Debug|x86 + {4F4E8EC4-C15D-42FC-8ADE-96F5F97F9C55}.Release|Any CPU.ActiveCfg = Release|x64 + {4F4E8EC4-C15D-42FC-8ADE-96F5F97F9C55}.Release|Any CPU.Build.0 = Release|x64 + {4F4E8EC4-C15D-42FC-8ADE-96F5F97F9C55}.Release|Any CPU.Deploy.0 = Release|x64 + {4F4E8EC4-C15D-42FC-8ADE-96F5F97F9C55}.Release|ARM.ActiveCfg = Release|x64 + {4F4E8EC4-C15D-42FC-8ADE-96F5F97F9C55}.Release|ARM.Build.0 = Release|x64 + {4F4E8EC4-C15D-42FC-8ADE-96F5F97F9C55}.Release|ARM.Deploy.0 = Release|x64 + {4F4E8EC4-C15D-42FC-8ADE-96F5F97F9C55}.Release|ARM64.ActiveCfg = Release|arm64 + {4F4E8EC4-C15D-42FC-8ADE-96F5F97F9C55}.Release|ARM64.Build.0 = Release|arm64 + {4F4E8EC4-C15D-42FC-8ADE-96F5F97F9C55}.Release|ARM64.Deploy.0 = Release|arm64 + {4F4E8EC4-C15D-42FC-8ADE-96F5F97F9C55}.Release|x64.ActiveCfg = Release|x64 + {4F4E8EC4-C15D-42FC-8ADE-96F5F97F9C55}.Release|x64.Build.0 = Release|x64 + {4F4E8EC4-C15D-42FC-8ADE-96F5F97F9C55}.Release|x64.Deploy.0 = Release|x64 + {4F4E8EC4-C15D-42FC-8ADE-96F5F97F9C55}.Release|x86.ActiveCfg = Release|x86 + {4F4E8EC4-C15D-42FC-8ADE-96F5F97F9C55}.Release|x86.Build.0 = Release|x86 + {4F4E8EC4-C15D-42FC-8ADE-96F5F97F9C55}.Release|x86.Deploy.0 = Release|x86 + {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Debug|ARM.ActiveCfg = Debug|Any CPU + {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Debug|ARM.Build.0 = Debug|Any CPU + {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Debug|ARM64.Build.0 = Debug|Any CPU + {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Debug|x64.ActiveCfg = Debug|Any CPU + {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Debug|x64.Build.0 = Debug|Any CPU + {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Debug|x86.ActiveCfg = Debug|Any CPU + {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Debug|x86.Build.0 = Debug|Any CPU + {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Release|Any CPU.Build.0 = Release|Any CPU + {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Release|ARM.ActiveCfg = Release|Any CPU + {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Release|ARM.Build.0 = Release|Any CPU + {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Release|ARM64.ActiveCfg = Release|Any CPU + {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Release|ARM64.Build.0 = Release|Any CPU + {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Release|x64.ActiveCfg = Release|Any CPU + {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Release|x64.Build.0 = Release|Any CPU + {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Release|x86.ActiveCfg = Release|Any CPU + {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Release|x86.Build.0 = Release|Any CPU + {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Debug|ARM.ActiveCfg = Debug|Any CPU + {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Debug|ARM.Build.0 = Debug|Any CPU + {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Debug|ARM64.Build.0 = Debug|Any CPU + {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Debug|x64.ActiveCfg = Debug|Any CPU + {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Debug|x64.Build.0 = Debug|Any CPU + {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Debug|x86.ActiveCfg = Debug|Any CPU + {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Debug|x86.Build.0 = Debug|Any CPU + {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Release|Any CPU.Build.0 = Release|Any CPU + {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Release|ARM.ActiveCfg = Release|Any CPU + {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Release|ARM.Build.0 = Release|Any CPU + {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Release|ARM64.ActiveCfg = Release|Any CPU + {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Release|ARM64.Build.0 = Release|Any CPU + {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Release|x64.ActiveCfg = Release|Any CPU + {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Release|x64.Build.0 = Release|Any CPU + {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Release|x86.ActiveCfg = Release|Any CPU + {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Release|x86.Build.0 = Release|Any CPU + {67FA8BC7-0C0D-4557-808B-BCE056C259CA}.Debug|Any CPU.ActiveCfg = Debug|x64 + {67FA8BC7-0C0D-4557-808B-BCE056C259CA}.Debug|Any CPU.Build.0 = Debug|x64 + {67FA8BC7-0C0D-4557-808B-BCE056C259CA}.Debug|Any CPU.Deploy.0 = Debug|x64 + {67FA8BC7-0C0D-4557-808B-BCE056C259CA}.Debug|ARM.ActiveCfg = Debug|x64 + {67FA8BC7-0C0D-4557-808B-BCE056C259CA}.Debug|ARM.Build.0 = Debug|x64 + {67FA8BC7-0C0D-4557-808B-BCE056C259CA}.Debug|ARM.Deploy.0 = Debug|x64 + {67FA8BC7-0C0D-4557-808B-BCE056C259CA}.Debug|ARM64.ActiveCfg = Debug|arm64 + {67FA8BC7-0C0D-4557-808B-BCE056C259CA}.Debug|ARM64.Build.0 = Debug|arm64 + {67FA8BC7-0C0D-4557-808B-BCE056C259CA}.Debug|ARM64.Deploy.0 = Debug|arm64 + {67FA8BC7-0C0D-4557-808B-BCE056C259CA}.Debug|x64.ActiveCfg = Debug|x64 + {67FA8BC7-0C0D-4557-808B-BCE056C259CA}.Debug|x64.Build.0 = Debug|x64 + {67FA8BC7-0C0D-4557-808B-BCE056C259CA}.Debug|x64.Deploy.0 = Debug|x64 + {67FA8BC7-0C0D-4557-808B-BCE056C259CA}.Debug|x86.ActiveCfg = Debug|x86 + {67FA8BC7-0C0D-4557-808B-BCE056C259CA}.Debug|x86.Build.0 = Debug|x86 + {67FA8BC7-0C0D-4557-808B-BCE056C259CA}.Debug|x86.Deploy.0 = Debug|x86 + {67FA8BC7-0C0D-4557-808B-BCE056C259CA}.Release|Any CPU.ActiveCfg = Release|x64 + {67FA8BC7-0C0D-4557-808B-BCE056C259CA}.Release|Any CPU.Build.0 = Release|x64 + {67FA8BC7-0C0D-4557-808B-BCE056C259CA}.Release|Any CPU.Deploy.0 = Release|x64 + {67FA8BC7-0C0D-4557-808B-BCE056C259CA}.Release|ARM.ActiveCfg = Release|x64 + {67FA8BC7-0C0D-4557-808B-BCE056C259CA}.Release|ARM.Build.0 = Release|x64 + {67FA8BC7-0C0D-4557-808B-BCE056C259CA}.Release|ARM.Deploy.0 = Release|x64 + {67FA8BC7-0C0D-4557-808B-BCE056C259CA}.Release|ARM64.ActiveCfg = Release|arm64 + {67FA8BC7-0C0D-4557-808B-BCE056C259CA}.Release|ARM64.Build.0 = Release|arm64 + {67FA8BC7-0C0D-4557-808B-BCE056C259CA}.Release|ARM64.Deploy.0 = Release|arm64 + {67FA8BC7-0C0D-4557-808B-BCE056C259CA}.Release|x64.ActiveCfg = Release|x64 + {67FA8BC7-0C0D-4557-808B-BCE056C259CA}.Release|x64.Build.0 = Release|x64 + {67FA8BC7-0C0D-4557-808B-BCE056C259CA}.Release|x64.Deploy.0 = Release|x64 + {67FA8BC7-0C0D-4557-808B-BCE056C259CA}.Release|x86.ActiveCfg = Release|x86 + {67FA8BC7-0C0D-4557-808B-BCE056C259CA}.Release|x86.Build.0 = Release|x86 + {67FA8BC7-0C0D-4557-808B-BCE056C259CA}.Release|x86.Deploy.0 = Release|x86 + {87F8E99E-6C8A-43BA-9FAC-F8FE49347FC2}.Debug|Any CPU.ActiveCfg = Debug|x64 + {87F8E99E-6C8A-43BA-9FAC-F8FE49347FC2}.Debug|Any CPU.Build.0 = Debug|x64 + {87F8E99E-6C8A-43BA-9FAC-F8FE49347FC2}.Debug|Any CPU.Deploy.0 = Debug|x64 + {87F8E99E-6C8A-43BA-9FAC-F8FE49347FC2}.Debug|ARM.ActiveCfg = Debug|ARM + {87F8E99E-6C8A-43BA-9FAC-F8FE49347FC2}.Debug|ARM.Build.0 = Debug|ARM + {87F8E99E-6C8A-43BA-9FAC-F8FE49347FC2}.Debug|ARM.Deploy.0 = Debug|ARM + {87F8E99E-6C8A-43BA-9FAC-F8FE49347FC2}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {87F8E99E-6C8A-43BA-9FAC-F8FE49347FC2}.Debug|ARM64.Build.0 = Debug|ARM64 + {87F8E99E-6C8A-43BA-9FAC-F8FE49347FC2}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {87F8E99E-6C8A-43BA-9FAC-F8FE49347FC2}.Debug|x64.ActiveCfg = Debug|x64 + {87F8E99E-6C8A-43BA-9FAC-F8FE49347FC2}.Debug|x64.Build.0 = Debug|x64 + {87F8E99E-6C8A-43BA-9FAC-F8FE49347FC2}.Debug|x64.Deploy.0 = Debug|x64 + {87F8E99E-6C8A-43BA-9FAC-F8FE49347FC2}.Debug|x86.ActiveCfg = Debug|x86 + {87F8E99E-6C8A-43BA-9FAC-F8FE49347FC2}.Debug|x86.Build.0 = Debug|x86 + {87F8E99E-6C8A-43BA-9FAC-F8FE49347FC2}.Debug|x86.Deploy.0 = Debug|x86 + {87F8E99E-6C8A-43BA-9FAC-F8FE49347FC2}.Release|Any CPU.ActiveCfg = Release|x64 + {87F8E99E-6C8A-43BA-9FAC-F8FE49347FC2}.Release|Any CPU.Build.0 = Release|x64 + {87F8E99E-6C8A-43BA-9FAC-F8FE49347FC2}.Release|Any CPU.Deploy.0 = Release|x64 + {87F8E99E-6C8A-43BA-9FAC-F8FE49347FC2}.Release|ARM.ActiveCfg = Release|ARM + {87F8E99E-6C8A-43BA-9FAC-F8FE49347FC2}.Release|ARM.Build.0 = Release|ARM + {87F8E99E-6C8A-43BA-9FAC-F8FE49347FC2}.Release|ARM.Deploy.0 = Release|ARM + {87F8E99E-6C8A-43BA-9FAC-F8FE49347FC2}.Release|ARM64.ActiveCfg = Release|ARM64 + {87F8E99E-6C8A-43BA-9FAC-F8FE49347FC2}.Release|ARM64.Build.0 = Release|ARM64 + {87F8E99E-6C8A-43BA-9FAC-F8FE49347FC2}.Release|ARM64.Deploy.0 = Release|ARM64 + {87F8E99E-6C8A-43BA-9FAC-F8FE49347FC2}.Release|x64.ActiveCfg = Release|x64 + {87F8E99E-6C8A-43BA-9FAC-F8FE49347FC2}.Release|x64.Build.0 = Release|x64 + {87F8E99E-6C8A-43BA-9FAC-F8FE49347FC2}.Release|x64.Deploy.0 = Release|x64 + {87F8E99E-6C8A-43BA-9FAC-F8FE49347FC2}.Release|x86.ActiveCfg = Release|x86 + {87F8E99E-6C8A-43BA-9FAC-F8FE49347FC2}.Release|x86.Build.0 = Release|x86 + {87F8E99E-6C8A-43BA-9FAC-F8FE49347FC2}.Release|x86.Deploy.0 = Release|x86 + {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Debug|ARM.ActiveCfg = Debug|Any CPU + {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Debug|ARM.Build.0 = Debug|Any CPU + {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Debug|ARM64.Build.0 = Debug|Any CPU + {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Debug|x64.ActiveCfg = Debug|Any CPU + {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Debug|x64.Build.0 = Debug|Any CPU + {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Debug|x86.ActiveCfg = Debug|Any CPU + {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Debug|x86.Build.0 = Debug|Any CPU + {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Release|Any CPU.Build.0 = Release|Any CPU + {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Release|ARM.ActiveCfg = Release|Any CPU + {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Release|ARM.Build.0 = Release|Any CPU + {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Release|ARM64.ActiveCfg = Release|Any CPU + {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Release|ARM64.Build.0 = Release|Any CPU + {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Release|x64.ActiveCfg = Release|Any CPU + {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Release|x64.Build.0 = Release|Any CPU + {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Release|x86.ActiveCfg = Release|Any CPU + {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Release|x86.Build.0 = Release|Any CPU + {1E97AC9F-CB43-4B98-AEF9-2BA035E037A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1E97AC9F-CB43-4B98-AEF9-2BA035E037A7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1E97AC9F-CB43-4B98-AEF9-2BA035E037A7}.Debug|ARM.ActiveCfg = Debug|ARM + {1E97AC9F-CB43-4B98-AEF9-2BA035E037A7}.Debug|ARM.Build.0 = Debug|ARM + {1E97AC9F-CB43-4B98-AEF9-2BA035E037A7}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {1E97AC9F-CB43-4B98-AEF9-2BA035E037A7}.Debug|ARM64.Build.0 = Debug|ARM64 + {1E97AC9F-CB43-4B98-AEF9-2BA035E037A7}.Debug|x64.ActiveCfg = Debug|x64 + {1E97AC9F-CB43-4B98-AEF9-2BA035E037A7}.Debug|x64.Build.0 = Debug|x64 + {1E97AC9F-CB43-4B98-AEF9-2BA035E037A7}.Debug|x86.ActiveCfg = Debug|x86 + {1E97AC9F-CB43-4B98-AEF9-2BA035E037A7}.Debug|x86.Build.0 = Debug|x86 + {1E97AC9F-CB43-4B98-AEF9-2BA035E037A7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1E97AC9F-CB43-4B98-AEF9-2BA035E037A7}.Release|Any CPU.Build.0 = Release|Any CPU + {1E97AC9F-CB43-4B98-AEF9-2BA035E037A7}.Release|ARM.ActiveCfg = Release|ARM + {1E97AC9F-CB43-4B98-AEF9-2BA035E037A7}.Release|ARM.Build.0 = Release|ARM + {1E97AC9F-CB43-4B98-AEF9-2BA035E037A7}.Release|ARM64.ActiveCfg = Release|ARM64 + {1E97AC9F-CB43-4B98-AEF9-2BA035E037A7}.Release|ARM64.Build.0 = Release|ARM64 + {1E97AC9F-CB43-4B98-AEF9-2BA035E037A7}.Release|x64.ActiveCfg = Release|x64 + {1E97AC9F-CB43-4B98-AEF9-2BA035E037A7}.Release|x64.Build.0 = Release|x64 + {1E97AC9F-CB43-4B98-AEF9-2BA035E037A7}.Release|x86.ActiveCfg = Release|x86 + {1E97AC9F-CB43-4B98-AEF9-2BA035E037A7}.Release|x86.Build.0 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {052083DA-908D-40A3-AD89-DCD26450A34C} = {25CC39A7-DB18-4A15-8E4A-5E0B1FF20DDE} + {FC69D0DF-E3E3-4135-BA9A-CBAA7C9025A7} = {25CC39A7-DB18-4A15-8E4A-5E0B1FF20DDE} + {4F4E8EC4-C15D-42FC-8ADE-96F5F97F9C55} = {25CC39A7-DB18-4A15-8E4A-5E0B1FF20DDE} + {66E6DA8A-FEFC-4221-A476-4314A4D692F6} = {326F9C50-2898-4589-8D40-25E9283F0D5A} + {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91} = {326F9C50-2898-4589-8D40-25E9283F0D5A} + {67FA8BC7-0C0D-4557-808B-BCE056C259CA} = {4CB70587-B61D-4C18-B831-E8B31EA714C5} + {87F8E99E-6C8A-43BA-9FAC-F8FE49347FC2} = {4CB70587-B61D-4C18-B831-E8B31EA714C5} + {79F79471-9947-45F5-81FE-4EBE2B8D0B1D} = {326F9C50-2898-4589-8D40-25E9283F0D5A} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {513719E1-6BD1-4C4A-A66F-489F67AEB31B} + EndGlobalSection + GlobalSection(SharedMSBuildProjectFiles) = preSolution + ..\..\common\CommunityToolkit.Labs.Shared\CommunityToolkit.Labs.Shared.projitems*{052083da-908d-40a3-ad89-dcd26450a34c}*SharedItemsImports = 4 + tests\CompositionCollectionView.Tests\CompositionCollectionView.Tests.projitems*{67fa8bc7-0c0d-4557-808b-bce056c259ca}*SharedItemsImports = 5 + tests\CompositionCollectionView.Tests\CompositionCollectionView.Tests.projitems*{69b7e819-dcf5-48f5-93da-5191416a1270}*SharedItemsImports = 13 + tests\CompositionCollectionView.Tests\CompositionCollectionView.Tests.projitems*{87f8e99e-6c8a-43ba-9fac-f8fe49347fc2}*SharedItemsImports = 4 + EndGlobalSection +EndGlobal diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/CompositionExtensions.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/CompositionExtensions.cs new file mode 100644 index 000000000..fe95b4710 --- /dev/null +++ b/labs/CompositionCollectionView/ExpressionsFork/Expressions/CompositionExtensions.cs @@ -0,0 +1,308 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Windows.UI.Composition; +using Windows.UI.Composition.Interactions; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork +{ + /// + /// Class CompositionExtensions. + /// + public static class CompositionExtensions + { + /// + /// Create an ExpressionNode reference to this CompositionObject. + /// + /// The comp object. + /// AmbientLightReferenceNode. + public static AmbientLightReferenceNode GetReference(this AmbientLight compObj) + { + return new AmbientLightReferenceNode(null, compObj); + } + + /// + /// Create an ExpressionNode reference to this CompositionObject. + /// + /// The comp object. + /// ColorBrushReferenceNode. + public static ColorBrushReferenceNode GetReference(this CompositionColorBrush compObj) + { + return new ColorBrushReferenceNode(null, compObj); + } + + /// + /// Create an ExpressionNode reference to this CompositionObject. + /// + /// The comp object. + /// DistantLightReferenceNode. + public static DistantLightReferenceNode GetReference(this DistantLight compObj) + { + return new DistantLightReferenceNode(null, compObj); + } + + /// + /// Create an ExpressionNode reference to this CompositionObject. + /// + /// The comp object. + /// DropShadowReferenceNode. + public static DropShadowReferenceNode GetReference(this DropShadow compObj) + { + return new DropShadowReferenceNode(null, compObj); + } + + /// + /// Create an ExpressionNode reference to this CompositionObject. + /// + /// The comp object. + /// InsetClipReferenceNode. + public static InsetClipReferenceNode GetReference(this InsetClip compObj) + { + return new InsetClipReferenceNode(null, compObj); + } + + /// + /// Create an ExpressionNode reference to this CompositionObject. + /// + /// The comp object. + /// InteractionTrackerReferenceNode. + public static InteractionTrackerReferenceNode GetReference(this InteractionTracker compObj) + { + return new InteractionTrackerReferenceNode(null, compObj); + } + + /// + /// Create an ExpressionNode reference to this CompositionObject. + /// + /// The comp object. + /// NineGridBrushReferenceNode. + public static NineGridBrushReferenceNode GetReference(this CompositionNineGridBrush compObj) + { + return new NineGridBrushReferenceNode(null, compObj); + } + + /// + /// Create an ExpressionNode reference to this CompositionObject. + /// + /// The comp object. + /// PointLightReferenceNode. + public static PointLightReferenceNode GetReference(this PointLight compObj) + { + return new PointLightReferenceNode(null, compObj); + } + + /// + /// Create an ExpressionNode reference to this CompositionObject. + /// + /// The comp object. + /// PropertySetReferenceNode. + public static PropertySetReferenceNode GetReference(this CompositionPropertySet compObj) + { + return new PropertySetReferenceNode(null, compObj); + } + + /// + /// Create an ExpressionNode reference to this CompositionObject. + /// + /// The comp object. + /// SpotLightReferenceNode. + public static SpotLightReferenceNode GetReference(this SpotLight compObj) + { + return new SpotLightReferenceNode(null, compObj); + } + + /// + /// Create an ExpressionNode reference to this CompositionObject. + /// + /// The comp object. + /// SurfaceBrushReferenceNode. + public static SurfaceBrushReferenceNode GetReference(this CompositionSurfaceBrush compObj) + { + return new SurfaceBrushReferenceNode(null, compObj); + } + + /// + /// Create an ExpressionNode reference to this CompositionObject. + /// + /// The comp object. + /// VisualReferenceNode. + public static VisualReferenceNode GetReference(this Visual compObj) + { + return new VisualReferenceNode(null, compObj); + } + + /// + /// Create an ExpressionNode reference to this specialized PropertySet. + /// + /// A class that derives from PropertySetReferenceNode. + /// The ps. + /// T. + /// Invalid property set specialization + public static T GetSpecializedReference(this CompositionPropertySet ps) + where T : PropertySetReferenceNode + { + if (typeof(T) == typeof(ManipulationPropertySetReferenceNode)) + { + return new ManipulationPropertySetReferenceNode(null, ps) as T; + } + else if (typeof(T) == typeof(PointerPositionPropertySetReferenceNode)) + { + return new PointerPositionPropertySetReferenceNode(null, ps) as T; + } + else + { + throw new System.Exception("Invalid property set specialization"); + } + } + + /// + /// Connects the specified ExpressionNode with the specified property of the object. + /// + /// The comp object. + /// The name of the property that the expression will target. + /// The root ExpressionNode that represents the ExpressionAnimation. + public static void StartAnimation(this CompositionObject compObject, string propertyName, ExpressionNode expressionNode) + { + compObject.StartAnimation(propertyName, CreateExpressionAnimationFromNode(compObject.Compositor, expressionNode)); + } + + /// + /// Inserts a KeyFrame whose value is calculated using the specified ExpressionNode. + /// + /// The keyframe animation. + /// The time the key frame should occur at, expressed as a percentage of the animation Duration. Allowed value is from 0.0 to 1.0. + /// The root ExpressionNode that represents the ExpressionAnimation. + /// The easing function to use when interpolating between frames. + public static void InsertExpressionKeyFrame(this KeyFrameAnimation keyframeAnimation, float normalizedProgressKey, ExpressionNode expressionNode, CompositionEasingFunction easing = null) + { + expressionNode.ClearReferenceInfo(); + + keyframeAnimation.InsertExpressionKeyFrame(normalizedProgressKey, expressionNode.ToExpressionString(), easing); + + expressionNode.SetAllParameters(keyframeAnimation); + } + + /// + /// Use the value of specified ExpressionNode to determine if this inertia modifier should be chosen. + /// + /// The modifier. + /// The root ExpressionNode that represents the ExpressionAnimation. + public static void SetCondition(this InteractionTrackerInertiaRestingValue modifier, ExpressionNode expressionNode) + { + modifier.Condition = CreateExpressionAnimationFromNode(modifier.Compositor, expressionNode); + } + + /// + /// Use the value of specified ExpressionNode as the resting value for this inertia modifier. + /// + /// The modifier. + /// The root ExpressionNode that represents the ExpressionAnimation. + public static void SetRestingValue(this InteractionTrackerInertiaRestingValue modifier, ExpressionNode expressionNode) + { + modifier.RestingValue = CreateExpressionAnimationFromNode(modifier.Compositor, expressionNode); + } + + /// + /// Use the value of specified ExpressionNode to determine if this inertia modifier should be chosen. + /// + /// The modifier. + /// The root ExpressionNode that represents the ExpressionAnimation. + public static void SetCondition(this InteractionTrackerInertiaMotion modifier, ExpressionNode expressionNode) + { + modifier.Condition = CreateExpressionAnimationFromNode(modifier.Compositor, expressionNode); + } + + /// + /// Use the value of specified ExpressionNode to dictate the motion for this inertia modifier. + /// + /// The modifier. + /// The root ExpressionNode that represents the ExpressionAnimation. + public static void SetMotion(this InteractionTrackerInertiaMotion modifier, ExpressionNode expressionNode) + { + modifier.Motion = CreateExpressionAnimationFromNode(modifier.Compositor, expressionNode); + } + + /// + /// Use the value of specified ExpressionNode to determine if this composition conditional value modifier should be chosen. + /// + /// The modifier. + /// The root ExpressionNode that represents the ExpressionAnimation. + public static void SetCondition(this CompositionConditionalValue modifier, ExpressionNode expressionNode) + { + modifier.Condition = CreateExpressionAnimationFromNode(modifier.Compositor, expressionNode); + } + + /// + /// Use the value of specified ExpressionNode as the value for this composition conditional value + /// + /// The modifier. + /// The root ExpressionNode that represents the ExpressionAnimation. + public static void SetValue(this CompositionConditionalValue modifier, ExpressionNode expressionNode) + { + modifier.Value = CreateExpressionAnimationFromNode(modifier.Compositor, expressionNode); + } + + /// + /// Creates the expression animation from node. + /// + /// The compositor. + /// The expression node. + /// ExpressionAnimation. + private static ExpressionAnimation CreateExpressionAnimationFromNode(Compositor compositor, ExpressionNode expressionNode) + { + // Only create a new animation if this node hasn't already generated one before, so we don't have to re-parse the expression string. + if (expressionNode.ExpressionAnimation == null) + { + expressionNode.ClearReferenceInfo(); + expressionNode.ExpressionAnimation = compositor.CreateExpressionAnimation(expressionNode.ToExpressionString()); + } + + // We need to make sure all parameters are up to date, even if the animation already existed. + expressionNode.SetAllParameters(expressionNode.ExpressionAnimation); + + return expressionNode.ExpressionAnimation; + } + + internal static float EvaluateSubchannel(this ExpressionNode node, string subchannel) => (node, subchannel) switch + { + (Vector2Node n, "X") => n.Evaluate().X, + (Vector2Node n, "Y") => n.Evaluate().Y, + + (Vector3Node n, "X") => n.Evaluate().X, + (Vector3Node n, "Y") => n.Evaluate().Y, + (Vector3Node n, "Z") => n.Evaluate().Z, + + (Vector4Node n, "X") => n.Evaluate().X, + (Vector4Node n, "Y") => n.Evaluate().Y, + (Vector4Node n, "Z") => n.Evaluate().Z, + (Vector4Node n, "W") => n.Evaluate().W, + + (Matrix3x2Node n, "Channel11") => n.Evaluate().M11, + (Matrix3x2Node n, "Channel12") => n.Evaluate().M12, + (Matrix3x2Node n, "Channel21") => n.Evaluate().M21, + (Matrix3x2Node n, "Channel22") => n.Evaluate().M22, + (Matrix3x2Node n, "Channel31") => n.Evaluate().M31, + (Matrix3x2Node n, "Channel32") => n.Evaluate().M32, + + (Matrix4x4Node n, "Channel11") => n.Evaluate().M11, + (Matrix4x4Node n, "Channel12") => n.Evaluate().M12, + (Matrix4x4Node n, "Channel13") => n.Evaluate().M13, + (Matrix4x4Node n, "Channel14") => n.Evaluate().M14, + (Matrix4x4Node n, "Channel21") => n.Evaluate().M21, + (Matrix4x4Node n, "Channel22") => n.Evaluate().M22, + (Matrix4x4Node n, "Channel23") => n.Evaluate().M23, + (Matrix4x4Node n, "Channel24") => n.Evaluate().M24, + (Matrix4x4Node n, "Channel31") => n.Evaluate().M31, + (Matrix4x4Node n, "Channel32") => n.Evaluate().M32, + (Matrix4x4Node n, "Channel33") => n.Evaluate().M33, + (Matrix4x4Node n, "Channel34") => n.Evaluate().M34, + (Matrix4x4Node n, "Channel41") => n.Evaluate().M41, + (Matrix4x4Node n, "Channel42") => n.Evaluate().M42, + (Matrix4x4Node n, "Channel43") => n.Evaluate().M43, + (Matrix4x4Node n, "Channel44") => n.Evaluate().M44, + + _ => 0 + }; + } +} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionFunctions.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionFunctions.cs new file mode 100644 index 000000000..205f53cd4 --- /dev/null +++ b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionFunctions.cs @@ -0,0 +1,1335 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork +{ + /// + /// Class ExpressionFunctions. + /// + public static class ExpressionFunctions + { + //TODO add all of these to evaluate() + + + /// + /// Returns the angle (in radians) whose cosine is the specified number. + /// + /// Value between -1 and 1, for which to calculate the arccosine (the inverse cosine). + /// ScalarNode. + public static ScalarNode ACos(ScalarNode val) + { + return Function(ExpressionNodeType.Acos, val); + } + + /// + /// Returns the angle (in radians) whose sine is the specified number. + /// + /// Value between -1 and 1, for which to calculate the arcsine (the inverse sine). + /// ScalarNode. + public static ScalarNode ASin(ScalarNode val) + { + return Function(ExpressionNodeType.Asin, val); + } + + /// + /// Returns the angle (in radians) whose tangent is the specified number. + /// + /// Value for which to calculate the arctan (the inverse tan). + /// ScalarNode. + public static ScalarNode ATan(ScalarNode val) + { + return Function(ExpressionNodeType.Atan, val); + } + + /// + /// Returns the smallest integral value that is greater than or equal to the specified value. + /// + /// The floating point number to round. + /// ScalarNode. + public static ScalarNode Ceil(ScalarNode val) + { + return Function(ExpressionNodeType.Ceil, val); + } + + /// + /// Returns the cosine of the specified angle (in radians). + /// + /// An angle, measured in radians. + /// ScalarNode. + public static ScalarNode Cos(ScalarNode val) + { + return Function(ExpressionNodeType.Cos, val); + } + + /// + /// Returns the largest integer less than or equal to the specified value. + /// + /// The floating point number to round. + /// ScalarNode. + public static ScalarNode Floor(ScalarNode val) + { + return Function(ExpressionNodeType.Floor, val); + } + + /// + /// Returns the natural (base e) logarithm of a specified number. + /// + /// The number whose natural logarithm is to be returned. + /// ScalarNode. + public static ScalarNode Ln(ScalarNode val) + { + return Function(ExpressionNodeType.Ln, val); + } + + /// + /// Returns the base 10 logarithm of a specified number. + /// + /// The number whose base 10 logarithm is to be calculated. + /// ScalarNode. + public static ScalarNode Log10(ScalarNode val) + { + return Function(ExpressionNodeType.Log10, val); + } + + /// + /// Returns a specified number raised to the specified power. + /// + /// A floating-point number to be raised to a power. + /// A floating-point number that specifies a power. + /// ScalarNode. + public static ScalarNode Pow(ScalarNode val1, ScalarNode val2) + { + return Function(ExpressionNodeType.Pow, val1, val2); + } + + /// + /// Rounds a floating point value to the nearest integral value. + /// + /// The floating point number to round. + /// ScalarNode. + public static ScalarNode Round(ScalarNode val) + { + return Function(ExpressionNodeType.Round, val); + } + + /// + /// Returns the sine of the specified angle (in radians). + /// + /// An angle, measured in radians. + /// ScalarNode. + public static ScalarNode Sin(ScalarNode val) + { + return Function(ExpressionNodeType.Sin, val); + } + + /// + /// Returns the specified number multiplied by itself. + /// + /// The floating point number to square. + /// ScalarNode. + public static ScalarNode Square(ScalarNode val) + { + return Function(ExpressionNodeType.Square, val); + } + + /// + /// Returns the square root of a specified number. + /// + /// The number whose square root is to be returned. + /// ScalarNode. + public static ScalarNode Sqrt(ScalarNode val) + { + return Function(ExpressionNodeType.Sqrt, val); + } + + /// + /// Returns the tangent of the specified angle (in radians). + /// + /// An angle, measured in radians. + /// ScalarNode. + public static ScalarNode Tan(ScalarNode val) + { + return Function(ExpressionNodeType.Tan, val); + } + + /// + /// Converts an angle in radians to degrees as: val*180/PI. + /// + /// A floating point value that represents an angle in radians. + /// ScalarNode. + public static ScalarNode ToDegrees(ScalarNode val) + { + return Function(ExpressionNodeType.ToDegrees, val); + } + + /// + /// Converts an angle in degrees to radians as: val*PI/180. + /// + /// A floating point value that represents an angle in degrees. + /// ScalarNode. + public static ScalarNode ToRadians(ScalarNode val) + { + return Function(ExpressionNodeType.ToRadians, val); + } + + // System.Numerics functions + + /// + /// Returns the absolute value of the specified input. For vectors, the absolute value of each subchannel is returned. + /// + /// The input value. + /// ScalarNode. + public static ScalarNode Abs(ScalarNode val) + { + return Function(ExpressionNodeType.Absolute, val); + } + + /// + /// Returns the absolute value of the specified input. For vectors, the absolute value of each subchannel is returned. + /// + /// The input value. + /// Vector2Node. + public static Vector2Node Abs(Vector2Node val) + { + return Function(ExpressionNodeType.Absolute, val); + } + + /// + /// Returns the absolute value of the specified input. For vectors, the absolute value of each subchannel is returned. + /// + /// The input value. + /// Vector3Node. + public static Vector3Node Abs(Vector3Node val) + { + return Function(ExpressionNodeType.Absolute, val); + } + + /// + /// Returns the absolute value of the specified input. For vectors, the absolute value of each subchannel is returned. + /// . + /// + /// The input value. + /// Vector4Node. + public static Vector4Node Abs(Vector4Node val) + { + return Function(ExpressionNodeType.Absolute, val); + } + + /// + /// Restricts a value to be within a specified range. For vectors, each subchannel is clamped. + /// + /// The value to clamp. + /// The specified minimum range. + /// The specified maximum range. + /// ScalarNode. + public static ScalarNode Clamp(ScalarNode val, ScalarNode min, ScalarNode max) + { + return Function(ExpressionNodeType.Clamp, val, min, max); + } + + /// + /// Restricts a value to be within a specified range. For vectors, each subchannel is clamped. + /// + /// The value to clamp. + /// The specified minimum range. + /// The specified maximum range. + /// Vector2Node. + public static Vector2Node Clamp(Vector2Node val, Vector2Node min, Vector2Node max) + { + return Function(ExpressionNodeType.Clamp, val, min, max); + } + + /// + /// Restricts a value to be within a specified range. For vectors, each subchannel is clamped. + /// + /// The value to clamp. + /// The specified minimum range. + /// The specified maximum range. + /// Vector3Node. + public static Vector3Node Clamp(Vector3Node val, Vector3Node min, Vector3Node max) + { + return Function(ExpressionNodeType.Clamp, val, min, max); + } + + /// + /// Restricts a value to be within a specified range. For vectors, each subchannel is clamped. + /// + /// The value to clamp. + /// The specified minimum range. + /// The specified maximum range. + /// Vector4Node. + public static Vector4Node Clamp(Vector4Node val, Vector4Node min, Vector4Node max) + { + return Function(ExpressionNodeType.Clamp, val, min, max); + } + + /// + /// Linearly interpolates between two colors in the default color space. + /// + /// Color source value 1. + /// Color source value 2. + /// A value between 0 and 1.0 indicating the weight of val2. + /// ColorNode. + public static ColorNode ColorLerp(ColorNode val1, ColorNode val2, ScalarNode progress) + { + return Function(ExpressionNodeType.ColorLerp, val1, val2, progress); + } + + /// + /// Linearly interpolates between two colors in the HSL color space. + /// + /// Color source value 1. + /// Color source value 2. + /// A value between 0 and 1.0 indicating the weight of val2. + /// ColorNode. + public static ColorNode ColorLerpHsl(ColorNode val1, ColorNode val2, ScalarNode progress) + { + return Function(ExpressionNodeType.ColorLerpHsl, val1, val2, progress); + } + + /// + /// Linearly interpolates between two colors in the RBG color space. + /// + /// Color source value 1. + /// Color source value 2. + /// A value between 0 and 1.0 indicating the weight of val2. + /// ColorNode. + public static ColorNode ColorLerpRgb(ColorNode val1, ColorNode val2, ScalarNode progress) + { + return Function(ExpressionNodeType.ColorLerpRgb, val1, val2, progress); + } + + /// + /// Concatenates two Quaternions; the result represents the first rotation followed by the second rotation. + /// + /// The first quaternion rotation in the series. + /// The second quaternion rotation in the series. + /// QuaternionNode. + public static QuaternionNode Concatenate(QuaternionNode val1, QuaternionNode val2) + { + return Function(ExpressionNodeType.Concatenate, val1, val2); + } + + /// + /// Returns the distance between two vectors as: sqrt((x1-x2)^2 + (y1-y2)^2 + ...). + /// + /// Source value 1. + /// Source value 2. + /// ScalarNode. + public static ScalarNode Distance(ScalarNode val1, ScalarNode val2) + { + return Function(ExpressionNodeType.Distance, val1, val2); + } + + /// + /// Returns the distance between two vectors as: sqrt((x1-x2)^2 + (y1-y2)^2 + ...). + /// + /// Source value 1. + /// Source value 2. + /// ScalarNode. + public static ScalarNode Distance(Vector2Node val1, Vector2Node val2) + { + return Function(ExpressionNodeType.Distance, val1, val2); + } + + /// + /// Returns the distance between two vectors as: sqrt((x1-x2)^2 + (y1-y2)^2 + ...). + /// + /// Source value 1. + /// Source value 2. + /// ScalarNode. + public static ScalarNode Distance(Vector3Node val1, Vector3Node val2) + { + return Function(ExpressionNodeType.Distance, val1, val2); + } + + /// + /// Returns the distance between two vectors as: sqrt((x1-x2)^2 + (y1-y2)^2 + ...). + /// + /// Source value 1. + /// Source value 2. + /// ScalarNode. + public static ScalarNode Distance(Vector4Node val1, Vector4Node val2) + { + return Function(ExpressionNodeType.Distance, val1, val2); + } + + /// + /// Returns the squared distance between two vectors as: ((x1-x2)^2 + (y1-y2)^2 + ...). + /// + /// Source value 1. + /// Source value 2. + /// ScalarNode. + public static ScalarNode DistanceSquared(ScalarNode val1, ScalarNode val2) + { + return Function(ExpressionNodeType.DistanceSquared, val1, val2); + } + + /// + /// Returns the squared distance between two vectors as: ((x1-x2)^2 + (y1-y2)^2 + ...). + /// + /// Source value 1. + /// Source value 2. + /// ScalarNode. + public static ScalarNode DistanceSquared(Vector2Node val1, Vector2Node val2) + { + return Function(ExpressionNodeType.DistanceSquared, val1, val2); + } + + /// + /// Returns the squared distance between two vectors as: ((x1-x2)^2 + (y1-y2)^2 + ...). + /// + /// Source value 1. + /// Source value 2. + /// ScalarNode. + public static ScalarNode DistanceSquared(Vector3Node val1, Vector3Node val2) + { + return Function(ExpressionNodeType.DistanceSquared, val1, val2); + } + + /// + /// Returns the squared distance between two vectors as: ((x1-x2)^2 + (y1-y2)^2 + ...). + /// + /// Source value 1. + /// Source value 2. + /// ScalarNode. + public static ScalarNode DistanceSquared(Vector4Node val1, Vector4Node val2) + { + return Function(ExpressionNodeType.DistanceSquared, val1, val2); + } + + /// + /// Returns the inverse of the specified matrix. + /// + /// The matrix to invert. + /// Matrix3x2Node. + public static Matrix3x2Node Inverse(Matrix3x2Node val) + { + return Function(ExpressionNodeType.Inverse, val); + } + + /// + /// Returns the inverse of the specified matrix. + /// + /// The matrix to invert. + /// Matrix4x4Node. + public static Matrix4x4Node Inverse(Matrix4x4Node val) + { + return Function(ExpressionNodeType.Inverse, val); + } + + /// + /// Returns the length of the vector as: sqrt(x^2 + y^2 + ...). + /// + /// Vector value to return the length of. + /// ScalarNode. + public static ScalarNode Length(ScalarNode val) + { + return Function(ExpressionNodeType.Length, val); + } + + /// + /// Returns the length of the vector as: sqrt(x^2 + y^2 + ...). + /// + /// Vector value to return the length of. + /// ScalarNode. + public static ScalarNode Length(Vector2Node val) + { + return Function(ExpressionNodeType.Length, val); + } + + /// + /// Returns the length of the vector as: sqrt(x^2 + y^2 + ...). + /// + /// Vector value to return the length of. + /// ScalarNode. + public static ScalarNode Length(Vector3Node val) + { + return Function(ExpressionNodeType.Length, val); + } + + /// + /// Returns the length of the vector as: sqrt(x^2 + y^2 + ...). + /// + /// Vector value to return the length of. + /// ScalarNode. + public static ScalarNode Length(Vector4Node val) + { + return Function(ExpressionNodeType.Length, val); + } + + /// + /// Returns the length of the vector as: sqrt(x^2 + y^2 + ...). + /// + /// Vector value to return the length of. + /// ScalarNode. + public static ScalarNode Length(QuaternionNode val) + { + return Function(ExpressionNodeType.Length, val); + } + + /// + /// Returns the squared length of the vector as: (x^2 + y^2 + ...). + /// + /// Vector value to return the length squared of. + /// ScalarNode. + public static ScalarNode LengthSquared(ScalarNode val) + { + return Function(ExpressionNodeType.LengthSquared, val); + } + + /// + /// Returns the squared length of the vector as: (x^2 + y^2 + ...). + /// + /// Vector value to return the length squared of. + /// ScalarNode. + public static ScalarNode LengthSquared(Vector2Node val) + { + return Function(ExpressionNodeType.LengthSquared, val); + } + + /// + /// Returns the squared length of the vector as: (x^2 + y^2 + ...). + /// + /// Vector value to return the length squared of. + /// ScalarNode. + public static ScalarNode LengthSquared(Vector3Node val) + { + return Function(ExpressionNodeType.LengthSquared, val); + } + + /// + /// Returns the squared length of the vector as: (x^2 + y^2 + ...). + /// + /// Vector value to return the length squared of. + /// ScalarNode. + public static ScalarNode LengthSquared(Vector4Node val) + { + return Function(ExpressionNodeType.LengthSquared, val); + } + + /// + /// Returns the squared length of the vector as: (x^2 + y^2 + ...). + /// + /// Vector value to return the length squared of. + /// ScalarNode. + public static ScalarNode LengthSquared(QuaternionNode val) + { + return Function(ExpressionNodeType.LengthSquared, val); + } + + /// + /// Linearly interpolates between two vectors as: Output.x = x1 + (x2-x1)*progress. + /// + /// Source value 1. + /// Source value 2. + /// A value between 0 and 1.0 indicating the weight of val2. + /// ScalarNode. + public static ScalarNode Lerp(ScalarNode val1, ScalarNode val2, ScalarNode progress) + { + return Function(ExpressionNodeType.Lerp, val1, val2, progress); + } + + /// + /// Linearly interpolates between two vectors as: Output.x = x1 + (x2-x1)*progress. + /// + /// Source value 1. + /// Source value 2. + /// A value between 0 and 1.0 indicating the weight of val2. + /// Vector2Node. + public static Vector2Node Lerp(Vector2Node val1, Vector2Node val2, ScalarNode progress) + { + return Function(ExpressionNodeType.Lerp, val1, val2, progress); + } + + /// + /// Linearly interpolates between two vectors as: Output.x = x1 + (x2-x1)*progress. + /// + /// Source value 1. + /// Source value 2. + /// A value between 0 and 1.0 indicating the weight of val2. + /// Vector3Node. + public static Vector3Node Lerp(Vector3Node val1, Vector3Node val2, ScalarNode progress) + { + return Function(ExpressionNodeType.Lerp, val1, val2, progress); + } + + /// + /// Linearly interpolates between two vectors as: Output.x = x1 + (x2-x1)*progress. + /// + /// Source value 1. + /// Source value 2. + /// A value between 0 and 1.0 indicating the weight of val2. + /// Vector4Node. + public static Vector4Node Lerp(Vector4Node val1, Vector4Node val2, ScalarNode progress) + { + return Function(ExpressionNodeType.Lerp, val1, val2, progress); + } + + /// + /// Returns the maximum of two values. For vectors, the max of each subchannel is returned. + /// + /// Source value 1. + /// Source value 2. + /// ScalarNode. + public static ScalarNode Max(ScalarNode val1, ScalarNode val2) + { + return Function(ExpressionNodeType.Max, val1, val2); + } + + /// + /// Returns the maximum of two values. For vectors, the max of each subchannel is returned. + /// + /// Source value 1. + /// Source value 2. + /// Vector2Node. + public static Vector2Node Max(Vector2Node val1, Vector2Node val2) + { + return Function(ExpressionNodeType.Max, val1, val2); + } + + /// + /// Returns the maximum of two values. For vectors, the max of each subchannel is returned. + /// + /// Source value 1. + /// Source value 2. + /// Vector3Node. + public static Vector3Node Max(Vector3Node val1, Vector3Node val2) + { + return Function(ExpressionNodeType.Max, val1, val2); + } + + /// + /// Returns the maximum of two values. For vectors, the max of each subchannel is returned. + /// + /// Source value 1. + /// Source value 2. + /// Vector4Node. + public static Vector4Node Max(Vector4Node val1, Vector4Node val2) + { + return Function(ExpressionNodeType.Max, val1, val2); + } + + /// + /// Returns the minimum of two values. For vectors, the min of each subchannel is returned. + /// + /// Source value 1. + /// Source value 2. + /// ScalarNode. + public static ScalarNode Min(ScalarNode val1, ScalarNode val2) + { + return Function(ExpressionNodeType.Min, val1, val2); + } + + /// + /// Returns the minimum of two values. For vectors, the min of each subchannel is returned. + /// + /// Source value 1. + /// Source value 2. + /// Vector2Node. + public static Vector2Node Min(Vector2Node val1, Vector2Node val2) + { + return Function(ExpressionNodeType.Min, val1, val2); + } + + /// + /// Returns the minimum of two values. For vectors, the min of each subchannel is returned. + /// + /// Source value 1. + /// Source value 2. + /// Vector3Node. + public static Vector3Node Min(Vector3Node val1, Vector3Node val2) + { + return Function(ExpressionNodeType.Min, val1, val2); + } + + /// + /// Returns the minimum of two values. For vectors, the min of each subchannel is returned. + /// + /// Source value 1. + /// Source value 2. + /// Vector4Node. + public static Vector4Node Min(Vector4Node val1, Vector4Node val2) + { + return Function(ExpressionNodeType.Min, val1, val2); + } + + /// + /// Returns the remainder resulting from dividing val1/val2. For vectors, the remainder for each subchannel is returned. + /// + /// The numerator value. + /// The denominator value. + /// ScalarNode. + public static ScalarNode Mod(ScalarNode val1, ScalarNode val2) + { + return Function(ExpressionNodeType.Modulus, val1, val2); + } + + /// + /// Returns the remainder resulting from dividing val1/val2. For vectors, the remainder for each subchannel is returned. + /// + /// The numerator value. + /// The denominator value. + /// Vector2Node. + public static Vector2Node Mod(Vector2Node val1, Vector2Node val2) + { + return Function(ExpressionNodeType.Modulus, val1, val2); + } + + /// + /// Returns the remainder resulting from dividing val1/val2. For vectors, the remainder for each subchannel is returned. + /// + /// The numerator value. + /// The denominator value. + /// Vector3Node. + public static Vector3Node Mod(Vector3Node val1, Vector3Node val2) + { + return Function(ExpressionNodeType.Modulus, val1, val2); + } + + /// + /// Returns the remainder resulting from dividing val1/val2. For vectors, the remainder for each subchannel is returned. + /// + /// The numerator value. + /// The denominator value. + /// Vector4Node. + public static Vector4Node Mod(Vector4Node val1, Vector4Node val2) + { + return Function(ExpressionNodeType.Modulus, val1, val2); + } + + /// + /// Returns the normalized version of a vector. + /// + /// Vector value to normalize. + /// Vector2Node. + public static Vector2Node Normalize(Vector2Node val) + { + return Function(ExpressionNodeType.Normalize, val); + } + + /// + /// Returns the normalized version of a vector. + /// + /// Vector value to normalize. + /// Vector3Node. + public static Vector3Node Normalize(Vector3Node val) + { + return Function(ExpressionNodeType.Normalize, val); + } + + /// + /// Returns the normalized version of a vector. + /// + /// Vector value to normalize. + /// Vector4Node. + public static Vector4Node Normalize(Vector4Node val) + { + return Function(ExpressionNodeType.Normalize, val); + } + + /// + /// Returns the normalized version of a vector. + /// + /// Vector value to normalize. + /// QuaternionNode. + public static QuaternionNode Normalize(QuaternionNode val) + { + return Function(ExpressionNodeType.Normalize, val); + } + + /// + /// Multiply each subchannel of the specified vector/matrix by a float value. + /// + /// Source value to scale. + /// Scaling value. + /// ScalarNode. + public static ScalarNode Scale(ScalarNode val1, ScalarNode val2) + { + return Function(ExpressionNodeType.Scale, val1, val2); + } + + /// + /// Multiply each subchannel of the specified vector/matrix by a float value. + /// + /// Source value to scale. + /// Scaling value. + /// Vector2Node. + public static Vector2Node Scale(Vector2Node val1, ScalarNode val2) + { + return Function(ExpressionNodeType.Scale, val1, val2); + } + + /// + /// Multiply each subchannel of the specified vector/matrix by a float value. + /// + /// Source value to scale. + /// Scaling value. + /// Vector3Node. + public static Vector3Node Scale(Vector3Node val1, ScalarNode val2) + { + return Function(ExpressionNodeType.Scale, val1, val2); + } + + /// + /// Multiply each subchannel of the specified vector/matrix by a float value. + /// + /// Source value to scale. + /// Scaling value. + /// Vector4Node. + public static Vector4Node Scale(Vector4Node val1, ScalarNode val2) + { + return Function(ExpressionNodeType.Scale, val1, val2); + } + + /// + /// Multiply each subchannel of the specified vector/matrix by a float value. + /// + /// Source value to scale. + /// Scaling value. + /// Matrix3x2Node. + public static Matrix3x2Node Scale(Matrix3x2Node val1, ScalarNode val2) + { + return Function(ExpressionNodeType.Scale, val1, val2); + } + + /// + /// Multiply each subchannel of the specified vector/matrix by a float value. + /// + /// Source value to scale. + /// Scaling value. + /// Matrix4x4Node. + public static Matrix4x4Node Scale(Matrix4x4Node val1, ScalarNode val2) + { + return Function(ExpressionNodeType.Scale, val1, val2); + } + + /// + /// Spherically interpolates between two quaternions. + /// + /// Quaternion source value 1. + /// Quaternion source value 2. + /// A value between 0 and 1.0 indicating the weight of val2. + /// QuaternionNode. + public static QuaternionNode Slerp(QuaternionNode val1, QuaternionNode val2, ScalarNode progress) + { + return Function(ExpressionNodeType.Slerp, val1, val2, progress); + } + + /// + /// Transforms a vector by the specified matrix. + /// + /// Vector to be transformed. + /// The transformation matrix. + /// Vector2Node. + public static Vector2Node Transform(Vector2Node val1, Matrix3x2Node val2) + { + return Function(ExpressionNodeType.Transform, val1, val2); + } + + /// + /// Transforms a vector by the specified matrix. + /// + /// Vector to be transformed. + /// The transformation matrix. + /// Vector4Node. + public static Vector4Node Transform(Vector4Node val1, Matrix4x4Node val2) + { + return Function(ExpressionNodeType.Transform, val1, val2); + } + + // System.Numerics Type Constructors + + /// + /// Creates a vector whose subchannels have the specified values. + /// + /// The x. + /// The y. + /// Vector2Node. + public static Vector2Node Vector2(ScalarNode x, ScalarNode y) + { + return Function(ExpressionNodeType.Vector2, x, y); + } + + /// + /// Creates a vector whose subchannels have the specified values. + /// + /// The x. + /// The y. + /// The z. + /// Vector3Node. + public static Vector3Node Vector3(ScalarNode x, ScalarNode y, ScalarNode z) + { + return Function(ExpressionNodeType.Vector3, x, y, z); + } + + /// + /// Creates a vector whose subchannels have the specified values. + /// + /// The x. + /// The y. + /// The z. + /// The w. + /// Vector4Node. + public static Vector4Node Vector4(ScalarNode x, ScalarNode y, ScalarNode z, ScalarNode w) + { + return Function(ExpressionNodeType.Vector4, x, y, z, w); + } + + /// + /// Creates a color in the HSL format. + /// + /// Hue + /// Saturation + /// Luminosity + /// ColorNode. + public static ColorNode ColorHsl(ScalarNode h, ScalarNode s, ScalarNode l) + { + return Function(ExpressionNodeType.ColorHsl, h, s, l); + } + + /// + /// Creates a Color in the ARGB format. + /// + /// The alpha. + /// The red. + /// The green. + /// The blue. + /// ColorNode. + public static ColorNode ColorRgb(ScalarNode alpha, ScalarNode red, ScalarNode green, ScalarNode blue) + { + return Function(ExpressionNodeType.ColorRgb, alpha, red, green, blue); + } + + /// + /// Creates a quaternion whose subchannels have the specified values. + /// + /// The x. + /// The y. + /// The z. + /// The w. + /// QuaternionNode. + public static QuaternionNode Quaternion(ScalarNode x, ScalarNode y, ScalarNode z, ScalarNode w) + { + return Function(ExpressionNodeType.Quaternion, x, y, z, w); + } + + /// + /// Creates a matrix whose subchannels have the specified values. + /// + /// The channel11. + /// The channel12. + /// The channel21. + /// The channel22. + /// The channel31. + /// The channel32. + /// Matrix3x2Node. + public static Matrix3x2Node Matrix3x2(ScalarNode channel11, ScalarNode channel12, ScalarNode channel21, ScalarNode channel22, ScalarNode channel31, ScalarNode channel32) + { + return Function(ExpressionNodeType.Matrix3x2, channel11, channel12, channel21, channel22, channel31, channel32); + } + + /// + /// Creates a matrix whose subchannels have the specified values. + /// + /// The channel11. + /// The channel12. + /// The channel13. + /// The channel14. + /// The channel21. + /// The channel22. + /// The channel23. + /// The channel24. + /// The channel31. + /// The channel32. + /// The channel33. + /// The channel34. + /// The channel41. + /// The channel42. + /// The channel43. + /// The channel44. + /// Matrix4x4Node. +#pragma warning disable SA1117 // Parameters must be on same line or separate lines + public static Matrix4x4Node Matrix4x4(ScalarNode channel11, ScalarNode channel12, ScalarNode channel13, ScalarNode channel14, + ScalarNode channel21, ScalarNode channel22, ScalarNode channel23, ScalarNode channel24, + ScalarNode channel31, ScalarNode channel32, ScalarNode channel33, ScalarNode channel34, + ScalarNode channel41, ScalarNode channel42, ScalarNode channel43, ScalarNode channel44) +#pragma warning restore SA1117 // Parameters must be on same line or separate lines + { + return Function(ExpressionNodeType.Matrix4x4, channel11, channel12, channel13, channel14, channel21, channel22, channel23, channel24, channel31, channel32, channel33, channel34, channel41, channel42, channel43, channel44); + } + + /// + /// Creates a 4x4 matrix from a 3x2 matrix. + /// + /// The value. + /// Matrix4x4Node. + public static Matrix4x4Node Matrix4x4(Matrix3x2Node val) + { +#pragma warning disable SA1117 // Parameters must be on same line or separate lines + return Function( + ExpressionNodeType.Matrix4x4, + val.Channel11, val.Channel12, (ScalarNode)0, (ScalarNode)0, + val.Channel21, val.Channel22, (ScalarNode)0, (ScalarNode)0, + (ScalarNode)0, (ScalarNode)0, (ScalarNode)1, (ScalarNode)0, + val.Channel31, val.Channel32, (ScalarNode)0, (ScalarNode)1); +#pragma warning restore SA1117 // Parameters must be on same line or separate lines + } + + /// + /// Creates a translation matrix from the specified vector. + /// + /// Source translation vector. + /// Matrix3x2Node. + public static Matrix3x2Node CreateTranslation(Vector2Node val) + { + return Function(ExpressionNodeType.Matrix3x2FromTranslation, val); + } + + /// + /// Creates a translation matrix from the specified vector. + /// + /// Source translation vector. + /// Matrix4x4Node. + public static Matrix4x4Node CreateTranslation(Vector3Node val) + { + return Function(ExpressionNodeType.Matrix4x4FromTranslation, val); + } + + /// + /// Creates a scale matrix from the specified vector scale. + /// + /// Source scaling vector. + /// Matrix3x2Node. + public static Matrix3x2Node CreateScale(Vector2Node val) + { + return Function(ExpressionNodeType.Matrix3x2FromScale, val); + } + + /// + /// Creates a scale matrix from the specified vector scale. + /// + /// Source scaling vector. + /// Matrix4x4Node. + public static Matrix4x4Node CreateScale(Vector3Node val) + { + return Function(ExpressionNodeType.Matrix4x4FromScale, val); + } + + /// + /// Creates a skew matrix from the specified angles in radians. + /// + /// X angle, in radians. + /// Y angle, in radians. + /// The centerpoint for the operation. + /// Matrix3x2Node. + public static Matrix3x2Node CreateSkew(ScalarNode xAngle, ScalarNode yAngle, Vector2Node centerPoint) + { + return Function(ExpressionNodeType.Matrix3x2FromSkew, xAngle, yAngle, centerPoint); + } + + /// + /// Creates a rotation matrix using the given rotation in radians. + /// + /// Angle, in radians. + /// Matrix3x2Node. + public static Matrix3x2Node CreateRotation(ScalarNode angle) + { + return Function(ExpressionNodeType.Matrix3x2FromRotation, angle); + } + + /// + /// Creates a matrix that rotates around an arbitrary vector. + /// + /// Rotation axis + /// Angle, in radians. + /// Matrix4x4Node. + public static Matrix4x4Node CreateMatrix4x4FromAxisAngle(Vector3Node axis, ScalarNode angle) + { + return Function(ExpressionNodeType.Matrix4x4FromAxisAngle, axis, angle); + } + + /// + /// Creates a quaternion that rotates around an arbitrary vector. + /// + /// Rotation axis + /// Angle, in radians. + /// QuaternionNode. + public static QuaternionNode CreateQuaternionFromAxisAngle(Vector3Node axis, ScalarNode angle) + { + return Function(ExpressionNodeType.QuaternionFromAxisAngle, axis, angle); + } + + /// + /// Performs a logical AND operation on two boolean values as: val1 && val2. + /// + /// The val1. + /// The val2. + /// BooleanNode. + public static BooleanNode And(BooleanNode val1, BooleanNode val2) + { + return Function(ExpressionNodeType.And, val1, val2); + } + + /// + /// Performs a logical OR operation on two boolean values as: val1 || val2. + /// + /// The val1. + /// The val2. + /// BooleanNode. + public static BooleanNode Or(BooleanNode val1, BooleanNode val2) + { + return Function(ExpressionNodeType.Or, val1, val2); + } + + /// + /// Performs a logical NOT operation on a specified boolean value as: !val. + /// + /// The value. + /// BooleanNode. + public static BooleanNode Not(BooleanNode val) + { + return Function(ExpressionNodeType.Not, val); + } + + /// + /// Returns one of two values, depending on the value of the boolean condition. + /// + /// Boolean value used to determine whether to return the value represented by 'trueCase' or 'falseCase'. + /// Value to return if 'condition' evaluates to true. + /// Value to return if 'condition' evaluates to false. + /// ScalarNode. + public static ScalarNode Conditional(BooleanNode condition, ScalarNode trueCase, ScalarNode falseCase) + { + return Function(ExpressionNodeType.Conditional, condition, trueCase, falseCase); + } + + /// + /// Returns one of two values, depending on the value of the boolean condition. + /// + /// Boolean value used to determine whether to return the value represented by 'trueCase' or 'falseCase'. + /// Value to return if 'condition' evaluates to true. + /// Value to return if 'condition' evaluates to false. + /// Vector2Node. + public static Vector2Node Conditional(BooleanNode condition, Vector2Node trueCase, Vector2Node falseCase) + { + return Function(ExpressionNodeType.Conditional, condition, trueCase, falseCase); + } + + /// + /// Returns one of two values, depending on the value of the boolean condition. + /// + /// Boolean value used to determine whether to return the value represented by 'trueCase' or 'falseCase'. + /// Value to return if 'condition' evaluates to true. + /// Value to return if 'condition' evaluates to false. + /// Vector3Node. + public static Vector3Node Conditional(BooleanNode condition, Vector3Node trueCase, Vector3Node falseCase) + { + return Function(ExpressionNodeType.Conditional, condition, trueCase, falseCase); + } + + /// + /// Returns one of two values, depending on the value of the boolean condition. + /// + /// Boolean value used to determine whether to return the value represented by 'trueCase' or 'falseCase'. + /// Value to return if 'condition' evaluates to true. + /// Value to return if 'condition' evaluates to false. + /// Vector4Node. + public static Vector4Node Conditional(BooleanNode condition, Vector4Node trueCase, Vector4Node falseCase) + { + return Function(ExpressionNodeType.Conditional, condition, trueCase, falseCase); + } + + /// + /// Returns one of two values, depending on the value of the boolean condition. + /// + /// Boolean value used to determine whether to return the value represented by 'trueCase' or 'falseCase'. + /// Value to return if 'condition' evaluates to true. + /// Value to return if 'condition' evaluates to false. + /// ColorNode. + public static ColorNode Conditional(BooleanNode condition, ColorNode trueCase, ColorNode falseCase) + { + return Function(ExpressionNodeType.Conditional, condition, trueCase, falseCase); + } + + /// + /// Returns one of two values, depending on the value of the boolean condition. + /// + /// Boolean value used to determine whether to return the value represented by 'trueCase' or 'falseCase'. + /// Value to return if 'condition' evaluates to true. + /// Value to return if 'condition' evaluates to false. + /// QuaternionNode. + public static QuaternionNode Conditional(BooleanNode condition, QuaternionNode trueCase, QuaternionNode falseCase) + { + return Function(ExpressionNodeType.Conditional, condition, trueCase, falseCase); + } + + /// + /// Returns one of two values, depending on the value of the boolean condition. + /// + /// Boolean value used to determine whether to return the value represented by 'trueCase' or 'falseCase'. + /// Value to return if 'condition' evaluates to true. + /// Value to return if 'condition' evaluates to false. + /// Matrix3x2Node. + public static Matrix3x2Node Conditional(BooleanNode condition, Matrix3x2Node trueCase, Matrix3x2Node falseCase) + { + return Function(ExpressionNodeType.Conditional, condition, trueCase, falseCase); + } + + /// + /// Returns one of two values, depending on the value of the boolean condition. + /// + /// Boolean value used to determine whether to return the value represented by 'trueCase' or 'falseCase'. + /// Value to return if 'condition' evaluates to true. + /// Value to return if 'condition' evaluates to false. + /// Matrix4x4Node. + public static Matrix4x4Node Conditional(BooleanNode condition, Matrix4x4Node trueCase, Matrix4x4Node falseCase) + { + return Function(ExpressionNodeType.Conditional, condition, trueCase, falseCase); + } + + /// + /// Functions the specified node type. + /// + /// A class that derives from ExpressionNode. + /// Type of the node. + /// The expression function parameters. + /// T. + internal static T Function(ExpressionNodeType nodeType, params ExpressionNode[] expressionFunctionParams) + where T : ExpressionNode + { + T newNode = ExpressionNode.CreateExpressionNode(); + + (newNode as ExpressionNode).NodeType = nodeType; + foreach (var param in expressionFunctionParams) + { + (newNode as ExpressionNode).Children.Add(param); + } + + return newNode; + } + + /// + /// Gets the type of the node information from. + /// + /// The type. + /// ExpressionNodeInfo. + internal static ExpressionNodeInfo GetNodeInfoFromType(ExpressionNodeType type) + { + return _expressionNodeInfo[type]; + } + + /// + /// Struct ExpressionNodeInfo + /// + internal struct ExpressionNodeInfo + { + /// + /// Initializes a new instance of the struct. + /// + /// Kind of the node operation. + /// The operation string. + public ExpressionNodeInfo(OperationType nodeOperationKind, string operationString) + { + NodeOperationKind = nodeOperationKind; + OperationString = operationString; + } + + /// + /// Gets or sets the kind of the node operation. + /// + /// The kind of the node operation. + internal OperationType NodeOperationKind { get; set; } + + /// + /// Gets or sets the operation string. + /// + /// The operation string. + internal string OperationString { get; set; } + } + + /// + /// The expression node information + /// + private static readonly Dictionary _expressionNodeInfo = new Dictionary + { + { ExpressionNodeType.ConstantValue, new ExpressionNodeInfo(OperationType.Constant, null) }, + { ExpressionNodeType.ConstantParameter, new ExpressionNodeInfo(OperationType.Constant, null) }, + { ExpressionNodeType.CurrentValueProperty, new ExpressionNodeInfo(OperationType.Reference, null) }, + { ExpressionNodeType.Reference, new ExpressionNodeInfo(OperationType.Reference, null) }, + { ExpressionNodeType.ReferenceProperty, new ExpressionNodeInfo(OperationType.Reference, null) }, + { ExpressionNodeType.StartingValueProperty, new ExpressionNodeInfo(OperationType.Reference, null) }, + { ExpressionNodeType.TargetReference, new ExpressionNodeInfo(OperationType.Reference, null) }, + { ExpressionNodeType.Conditional, new ExpressionNodeInfo(OperationType.Conditional, null) }, + { ExpressionNodeType.Swizzle, new ExpressionNodeInfo(OperationType.Swizzle, null) }, + { ExpressionNodeType.Add, new ExpressionNodeInfo(OperationType.Operator, "+") }, + { ExpressionNodeType.And, new ExpressionNodeInfo(OperationType.Operator, "&&") }, + { ExpressionNodeType.Divide, new ExpressionNodeInfo(OperationType.Operator, "/") }, + { ExpressionNodeType.Equals, new ExpressionNodeInfo(OperationType.Operator, "==") }, + { ExpressionNodeType.GreaterThan, new ExpressionNodeInfo(OperationType.Operator, ">") }, + { ExpressionNodeType.GreaterThanEquals, new ExpressionNodeInfo(OperationType.Operator, ">=") }, + { ExpressionNodeType.LessThan, new ExpressionNodeInfo(OperationType.Operator, "<") }, + { ExpressionNodeType.LessThanEquals, new ExpressionNodeInfo(OperationType.Operator, "<=") }, + { ExpressionNodeType.Multiply, new ExpressionNodeInfo(OperationType.Operator, "*") }, + { ExpressionNodeType.Not, new ExpressionNodeInfo(OperationType.UnaryOperator, "!") }, + { ExpressionNodeType.NotEquals, new ExpressionNodeInfo(OperationType.Operator, "!=") }, + { ExpressionNodeType.Or, new ExpressionNodeInfo(OperationType.Operator, "||") }, + { ExpressionNodeType.Subtract, new ExpressionNodeInfo(OperationType.Operator, "-") }, + { ExpressionNodeType.Absolute, new ExpressionNodeInfo(OperationType.Function, "abs") }, + { ExpressionNodeType.Acos, new ExpressionNodeInfo(OperationType.Function, "acos") }, + { ExpressionNodeType.Asin, new ExpressionNodeInfo(OperationType.Function, "asin") }, + { ExpressionNodeType.Atan, new ExpressionNodeInfo(OperationType.Function, "atan") }, + { ExpressionNodeType.Cos, new ExpressionNodeInfo(OperationType.Function, "cos") }, + { ExpressionNodeType.Ceil, new ExpressionNodeInfo(OperationType.Function, "ceil") }, + { ExpressionNodeType.Clamp, new ExpressionNodeInfo(OperationType.Function, "clamp") }, + { ExpressionNodeType.ColorHsl, new ExpressionNodeInfo(OperationType.Function, "colorhsl") }, + { ExpressionNodeType.ColorRgb, new ExpressionNodeInfo(OperationType.Function, "colorrgb") }, + { ExpressionNodeType.ColorLerp, new ExpressionNodeInfo(OperationType.Function, "colorlerp") }, + { ExpressionNodeType.ColorLerpHsl, new ExpressionNodeInfo(OperationType.Function, "colorhsllerp") }, + { ExpressionNodeType.ColorLerpRgb, new ExpressionNodeInfo(OperationType.Function, "colorrgblerp") }, + { ExpressionNodeType.Concatenate, new ExpressionNodeInfo(OperationType.Function, "concatenate") }, + { ExpressionNodeType.Distance, new ExpressionNodeInfo(OperationType.Function, "distance") }, + { ExpressionNodeType.DistanceSquared, new ExpressionNodeInfo(OperationType.Function, "distancesquared") }, + { ExpressionNodeType.Floor, new ExpressionNodeInfo(OperationType.Function, "floor") }, + { ExpressionNodeType.Inverse, new ExpressionNodeInfo(OperationType.Function, "inverse") }, + { ExpressionNodeType.Length, new ExpressionNodeInfo(OperationType.Function, "length") }, + { ExpressionNodeType.LengthSquared, new ExpressionNodeInfo(OperationType.Function, "lengthsquared") }, + { ExpressionNodeType.Lerp, new ExpressionNodeInfo(OperationType.Function, "lerp") }, + { ExpressionNodeType.Ln, new ExpressionNodeInfo(OperationType.Function, "ln") }, + { ExpressionNodeType.Log10, new ExpressionNodeInfo(OperationType.Function, "log10") }, + { ExpressionNodeType.Max, new ExpressionNodeInfo(OperationType.Function, "max") }, + { ExpressionNodeType.Matrix3x2FromRotation, new ExpressionNodeInfo(OperationType.Function, "matrix3x2.createrotation") }, + { ExpressionNodeType.Matrix3x2FromScale, new ExpressionNodeInfo(OperationType.Function, "matrix3x2.createscale") }, + { ExpressionNodeType.Matrix3x2FromSkew, new ExpressionNodeInfo(OperationType.Function, "matrix3x2.createskew") }, + { ExpressionNodeType.Matrix3x2FromTranslation, new ExpressionNodeInfo(OperationType.Function, "matrix3x2.createtranslation") }, + { ExpressionNodeType.Matrix3x2, new ExpressionNodeInfo(OperationType.Function, "matrix3x2") }, + { ExpressionNodeType.Matrix4x4FromAxisAngle, new ExpressionNodeInfo(OperationType.Function, "matrix4x4.createfromaxisangle") }, + { ExpressionNodeType.Matrix4x4FromScale, new ExpressionNodeInfo(OperationType.Function, "matrix4x4.createscale") }, + { ExpressionNodeType.Matrix4x4FromTranslation, new ExpressionNodeInfo(OperationType.Function, "matrix4x4.createtranslation") }, + { ExpressionNodeType.Matrix4x4, new ExpressionNodeInfo(OperationType.Function, "matrix4x4") }, + { ExpressionNodeType.Min, new ExpressionNodeInfo(OperationType.Function, "min") }, + { ExpressionNodeType.Modulus, new ExpressionNodeInfo(OperationType.Function, "mod") }, + { ExpressionNodeType.Negate, new ExpressionNodeInfo(OperationType.Function, "-") }, + { ExpressionNodeType.Normalize, new ExpressionNodeInfo(OperationType.Function, "normalize") }, + { ExpressionNodeType.Pow, new ExpressionNodeInfo(OperationType.Function, "pow") }, + { ExpressionNodeType.QuaternionFromAxisAngle, new ExpressionNodeInfo(OperationType.Function, "quaternion.createfromaxisangle") }, + { ExpressionNodeType.Quaternion, new ExpressionNodeInfo(OperationType.Function, "quaternion") }, + { ExpressionNodeType.Round, new ExpressionNodeInfo(OperationType.Function, "round") }, + { ExpressionNodeType.Scale, new ExpressionNodeInfo(OperationType.Function, "scale") }, + { ExpressionNodeType.Sin, new ExpressionNodeInfo(OperationType.Function, "sin") }, + { ExpressionNodeType.Slerp, new ExpressionNodeInfo(OperationType.Function, "slerp") }, + { ExpressionNodeType.Sqrt, new ExpressionNodeInfo(OperationType.Function, "sqrt") }, + { ExpressionNodeType.Square, new ExpressionNodeInfo(OperationType.Function, "square") }, + { ExpressionNodeType.Tan, new ExpressionNodeInfo(OperationType.Function, "tan") }, + { ExpressionNodeType.ToDegrees, new ExpressionNodeInfo(OperationType.Function, "todegrees") }, + { ExpressionNodeType.ToRadians, new ExpressionNodeInfo(OperationType.Function, "toradians") }, + { ExpressionNodeType.Transform, new ExpressionNodeInfo(OperationType.Function, "transform") }, + { ExpressionNodeType.Vector2, new ExpressionNodeInfo(OperationType.Function, "vector2") }, + { ExpressionNodeType.Vector3, new ExpressionNodeInfo(OperationType.Function, "vector3") }, + { ExpressionNodeType.Vector4, new ExpressionNodeInfo(OperationType.Function, "vector4") }, + }; + } +} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/BooleanNode.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/BooleanNode.cs new file mode 100644 index 000000000..0b4dca317 --- /dev/null +++ b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/BooleanNode.cs @@ -0,0 +1,195 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork +{ + // Ignore warning: 'BooleanNode' defines operator == or operator != but does not override Object.Equals(object o) && Object.GetHashCode() +#pragma warning disable CS0660, CS0661 + /// + /// Class BooleanNode. This class cannot be inherited. + /// + /// + public sealed class BooleanNode : ExpressionNode + { + /// + /// Initializes a new instance of the class. + /// + internal BooleanNode() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// if set to true [value]. + internal BooleanNode(bool value) + { + _value = value; + NodeType = ExpressionNodeType.ConstantValue; + } + + /// + /// Initializes a new instance of the class. + /// + /// Name of the parameter. + internal BooleanNode(string paramName) + { + ParamName = paramName; + NodeType = ExpressionNodeType.ConstantParameter; + } + + /// + /// Initializes a new instance of the class. + /// + /// Name of the parameter. + /// if set to true [value]. + internal BooleanNode(string paramName, bool value) + { + ParamName = paramName; + _value = value; + NodeType = ExpressionNodeType.ConstantParameter; + + SetBooleanParameter(paramName, value); + } + + /// + /// Performs an implicit conversion from to . + /// + /// if set to true [value]. + /// The result of the conversion. + public static implicit operator BooleanNode(bool value) + { + return new BooleanNode(value); + } + + /// + /// Implements the == operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static BooleanNode operator ==(BooleanNode left, BooleanNode right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Equals, left, right); + } + + /// + /// Implements the != operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static BooleanNode operator !=(BooleanNode left, BooleanNode right) + { + return ExpressionFunctions.Function(ExpressionNodeType.NotEquals, left, right); + } + + /// + /// Implements the & operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static BooleanNode operator &(BooleanNode left, BooleanNode right) + { + return ExpressionFunctions.Function(ExpressionNodeType.And, left, right); + } + + /// + /// Implements the | operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static BooleanNode operator |(BooleanNode left, BooleanNode right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Or, left, right); + } + + /// + /// Implements the ! operator. + /// + /// The value. + /// The result of the operator. + public static BooleanNode operator !(BooleanNode value) + { + return ExpressionFunctions.Function(ExpressionNodeType.Not, value); + } + + /// + /// Gets the value. + /// + /// System.String. + protected internal override string GetValue() + { + return _value ? "true" : "false"; + } + + private bool _value; + + /// + /// Evaluates the current value of the expression + /// + /// The current value of the expression + public bool Evaluate() + { + switch (NodeType) + { + case ExpressionNodeType.ConstantValue: + return _value; + case ExpressionNodeType.Equals: + return Equals(Children[0], Children[1]); + case ExpressionNodeType.NotEquals: + return !Equals(Children[0], Children[1]); + case ExpressionNodeType.And: + return (Children[0] as BooleanNode).Evaluate() && (Children[1] as BooleanNode).Evaluate(); + case ExpressionNodeType.Or: + return (Children[0] as BooleanNode).Evaluate() || (Children[1] as BooleanNode).Evaluate(); + case ExpressionNodeType.LessThan: + return (Children[0] as ScalarNode).Evaluate() < (Children[1] as ScalarNode).Evaluate(); + case ExpressionNodeType.LessThanEquals: + return (Children[0] as ScalarNode).Evaluate() <= (Children[1] as ScalarNode).Evaluate(); + case ExpressionNodeType.GreaterThan: + return (Children[0] as ScalarNode).Evaluate() > (Children[1] as ScalarNode).Evaluate(); + case ExpressionNodeType.GreaterThanEquals: + return (Children[0] as ScalarNode).Evaluate() >= (Children[1] as ScalarNode).Evaluate(); + case ExpressionNodeType.Not: + return !(Children[0] as BooleanNode).Evaluate(); + case ExpressionNodeType.ReferenceProperty: + var reference = (Children[0] as ReferenceNode).Reference; + switch (PropertyName) + { + default: + reference.Properties.TryGetBoolean(PropertyName, out var referencedProperty); + return referencedProperty; + } + + case ExpressionNodeType.Conditional: + return + (Children[0] as BooleanNode).Evaluate() ? + (Children[1] as BooleanNode).Evaluate() : + (Children[2] as BooleanNode).Evaluate(); + default: + throw new NotImplementedException(); + } + + bool Equals(ExpressionNode e1, ExpressionNode e2) => (e1, e2) switch + { + (BooleanNode n1, BooleanNode n2) => n1.Evaluate() == n2.Evaluate(), + (ScalarNode n1, ScalarNode n2) => n1.Evaluate() == n2.Evaluate(), + (Vector2Node n1, Vector2Node n2) => n1.Evaluate() == n2.Evaluate(), + (Vector3Node n1, Vector3Node n2) => n1.Evaluate() == n2.Evaluate(), + (Vector4Node n1, Vector4Node n2) => n1.Evaluate() == n2.Evaluate(), + (ColorNode n1, ColorNode n2) => n1.Evaluate() == n2.Evaluate(), + (QuaternionNode n1, QuaternionNode n2) => n1.Evaluate() == n2.Evaluate(), + (Matrix3x2Node n1, Matrix3x2Node n2) => n1.Evaluate() == n2.Evaluate(), + (Matrix4x4Node n1, Matrix4x4Node n2) => n1.Evaluate() == n2.Evaluate(), + _ => false + }; + } + } +#pragma warning restore CS0660, CS0661 +} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/ColorNode.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/ColorNode.cs new file mode 100644 index 000000000..b0566e70a --- /dev/null +++ b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/ColorNode.cs @@ -0,0 +1,138 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Windows.UI; +using Windows.UI.Composition; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork +{ + // Ignore warning: 'ColorNode' defines operator == or operator != but does not override Object.Equals(object o) && Object.GetHashCode() +#pragma warning disable CS0660, CS0661 + /// + /// Class ColorNode. This class cannot be inherited. + /// + /// + public sealed class ColorNode : ExpressionNode + { + /// + /// Initializes a new instance of the class. + /// + internal ColorNode() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The value. + internal ColorNode(Color value) + { + _value = value; + NodeType = ExpressionNodeType.ConstantValue; + } + + /// + /// Initializes a new instance of the class. + /// + /// Name of the parameter. + internal ColorNode(string paramName) + { + ParamName = paramName; + NodeType = ExpressionNodeType.ConstantParameter; + } + + /// + /// Initializes a new instance of the class. + /// + /// Name of the parameter. + /// The value. + internal ColorNode(string paramName, Color value) + { + ParamName = paramName; + _value = value; + NodeType = ExpressionNodeType.ConstantParameter; + + SetColorParameter(paramName, value); + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value. + /// The result of the conversion. + public static implicit operator ColorNode(Color value) + { + return new ColorNode(value); + } + + /// + /// Implements the == operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static BooleanNode operator ==(ColorNode left, ColorNode right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Equals, left, right); + } + + /// + /// Implements the != operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static BooleanNode operator !=(ColorNode left, ColorNode right) + { + return ExpressionFunctions.Function(ExpressionNodeType.NotEquals, left, right); + } + + /// + /// Gets the value. + /// + /// System.String. + protected internal override string GetValue() + { + return $"ColorRgb({_value.A},{_value.R},{_value.G},{_value.B})"; + } + + private Color _value; + + /// + /// Evaluates the current value of the expression + /// + /// The current value of the expression + public Color Evaluate() + { + switch (NodeType) + { + case ExpressionNodeType.ConstantValue: + return _value; + case ExpressionNodeType.ReferenceProperty: + var reference = (Children[0] as ReferenceNode).Reference; + return PropertyName switch + { + nameof(CompositionColorBrush.Color) => (reference as CompositionColorBrush).Color, + _ => GetProperty() + }; + + Color GetProperty() + { + reference.Properties.TryGetColor(PropertyName, out var value); + return value; + } + + case ExpressionNodeType.Conditional: + return + (Children[0] as BooleanNode).Evaluate() ? + (Children[1] as ColorNode).Evaluate() : + (Children[2] as ColorNode).Evaluate(); + default: + throw new NotImplementedException(); + } + } + } +#pragma warning restore CS0660, CS0661 +} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/ExpressionNode.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/ExpressionNode.cs new file mode 100644 index 000000000..e97bbee51 --- /dev/null +++ b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/ExpressionNode.cs @@ -0,0 +1,720 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Numerics; +using System.Runtime.CompilerServices; +using Windows.UI; +using Windows.UI.Composition; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork +{ + /// + /// Class ExpressionNode. + /// + public abstract class ExpressionNode : IDisposable + { + private List _objRefList = null; + private Dictionary _compObjToParamNameMap = null; + private Dictionary _constParamMap = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + + /// + /// Initializes a new instance of the class. + /// + internal ExpressionNode() + { + } + + /// + /// Resolve a named reference parameter to the CompositionObject it will refer to. + /// + /// The string name of the parameter to be resolved. + /// The composition object that the parameter should resolve to. + public void SetReferenceParameter(string parameterName, CompositionObject compObj) + { + // Make sure we have our reference list populated + EnsureReferenceInfo(); + + for (int i = 0; i < _objRefList.Count; i++) + { + if (string.Compare(_objRefList[i].ParameterName, parameterName, true /*ignoreCase*/) == 0) + { + var item = _objRefList[i]; + item.CompObject = compObj; + _objRefList[i] = item; + } + } + } + + /// + /// Resolve a named parameter to the boolean value it will use. + /// + /// The string name of the parameter to be resolved. + /// The value that the parameter should resolve to. + public void SetBooleanParameter(string parameterName, bool value) + { + _constParamMap[parameterName] = value; + } + + /// + /// Resolve a named parameter to the float value it will use. + /// + /// The string name of the parameter to be resolved. + /// The value that the parameter should resolve to. + public void SetScalarParameter(string parameterName, float value) + { + _constParamMap[parameterName] = value; + } + + /// + /// Resolve a named parameter to the Vector2 value it will use. + /// + /// The string name of the parameter to be resolved. + /// The value that the parameter should resolve to. + public void SetVector2Parameter(string parameterName, Vector2 value) + { + _constParamMap[parameterName] = value; + } + + /// + /// Resolve a named parameter to the Vector3 value it will use. + /// + /// The string name of the parameter to be resolved. + /// The value that the parameter should resolve to. + public void SetVector3Parameter(string parameterName, Vector3 value) + { + _constParamMap[parameterName] = value; + } + + /// + /// Resolve a named parameter to the Vector4 value it will use. + /// + /// The string name of the parameter to be resolved. + /// The value that the parameter should resolve to. + public void SetVector4Parameter(string parameterName, Vector4 value) + { + _constParamMap[parameterName] = value; + } + + /// + /// Resolve a named parameter to the Color value it will use. + /// + /// The string name of the parameter to be resolved. + /// The value that the parameter should resolve to. + public void SetColorParameter(string parameterName, Color value) + { + _constParamMap[parameterName] = value; + } + + /// + /// Resolve a named parameter to the Quaternion value it will use. + /// + /// The string name of the parameter to be resolved. + /// The value that the parameter should resolve to. + public void SetQuaternionParameter(string parameterName, Quaternion value) + { + _constParamMap[parameterName] = value; + } + + /// + /// Resolve a named parameter to the Matrix3x2 value it will use. + /// + /// The string name of the parameter to be resolved. + /// The value that the parameter should resolve to. + public void SetMatrix3x2Parameter(string parameterName, Matrix3x2 value) + { + _constParamMap[parameterName] = value; + } + + /// + /// Resolve a named parameter to the Matrix4x4 value it will use. + /// + /// The string name of the parameter to be resolved. + /// The value that the parameter should resolve to. + public void SetMatrix4x4Parameter(string parameterName, Matrix4x4 value) + { + _constParamMap[parameterName] = value; + } + + /// + /// Releases all resources used by this ExpressionNode. + /// + public void Dispose() + { + _objRefList = null; + _compObjToParamNameMap = null; + _constParamMap = null; + Subchannels = null; + PropertyName = null; + NodeType = ExpressionNodeType.Count; + + // Note: we don't recursively dispose all child nodes, as those nodes could be in use by a different Expression + Children = null; + + if (ExpressionAnimation != null) + { + ExpressionAnimation.Dispose(); + ExpressionAnimation = null; + } + } + + /// + /// Creates the expression node. + /// + /// A class that derives from ExpressionNode + /// T. + /// unexpected type + internal static T CreateExpressionNode() + where T : ExpressionNode + { + T newNode; + + if (typeof(T) == typeof(BooleanNode)) + { + newNode = new BooleanNode() as T; + } + else if (typeof(T) == typeof(ScalarNode)) + { + newNode = new ScalarNode() as T; + } + else if (typeof(T) == typeof(Vector2Node)) + { + newNode = new Vector2Node() as T; + } + else if (typeof(T) == typeof(Vector3Node)) + { + newNode = new Vector3Node() as T; + } + else if (typeof(T) == typeof(Vector4Node)) + { + newNode = new Vector4Node() as T; + } + else if (typeof(T) == typeof(ColorNode)) + { + newNode = new ColorNode() as T; + } + else if (typeof(T) == typeof(QuaternionNode)) + { + newNode = new QuaternionNode() as T; + } + else if (typeof(T) == typeof(Matrix3x2Node)) + { + newNode = new Matrix3x2Node() as T; + } + else if (typeof(T) == typeof(Matrix4x4Node)) + { + newNode = new Matrix4x4Node() as T; + } + else + { + throw new Exception("unexpected type"); + } + + return newNode; + } + + /// + /// Creates the value keyword. + /// + /// A class that derives from ExpressionNode + /// Kind of the keyword. + /// T. + /// Invalid ValueKeywordKind + internal static T CreateValueKeyword(ValueKeywordKind keywordKind) + where T : ExpressionNode + { + T node = CreateExpressionNode(); + + (node as ExpressionNode).ParamName = null; + + switch (keywordKind) + { + case ValueKeywordKind.CurrentValue: + (node as ExpressionNode).NodeType = ExpressionNodeType.CurrentValueProperty; + break; + + case ValueKeywordKind.StartingValue: + (node as ExpressionNode).NodeType = ExpressionNodeType.StartingValueProperty; + break; + + default: + throw new Exception("Invalid ValueKeywordKind"); + } + + return node; + } + + /// + /// To the expression string. + /// + /// System.String. + internal string ToExpressionString() + { + if (_objRefList == null) + { + EnsureReferenceInfo(); + } + + return ToExpressionStringInternal(); + } + + /// + /// Clears the reference information. + /// + /// Reference and paramName can't both be null + internal void ClearReferenceInfo() + { + _objRefList = null; + ParamName = null; + foreach (var child in Children) + { + child.ClearReferenceInfo(); + } + } + + /// + /// Ensures the reference information. + /// + /// Reference and paramName can't both be null + internal void EnsureReferenceInfo() + { + if (_objRefList == null) + { + // Get all ReferenceNodes in this expression + HashSet referenceNodes = new HashSet(); + PopulateParameterNodes(ref _constParamMap, ref referenceNodes); + + // Find all CompositionObjects across all referenceNodes that need a paramName to be created + HashSet compObjects = new HashSet(); + foreach (var refNode in referenceNodes) + { + if ((refNode.Reference != null) && (refNode.GetReferenceParamString() == null)) + { + compObjects.Add(refNode.Reference); + } + } + + // Create a map to store the generated paramNames for each CompObj + _compObjToParamNameMap = new Dictionary(); + var paramCount = 0u; + foreach (var compObj in compObjects) + { + string paramName = CreateUniqueParamNameFromIndex(paramCount++); + + _compObjToParamNameMap.Add(compObj, paramName); + } + + // Go through all reference nodes again to create our full list of referenceInfo. This time, if + // the param name is null, look it up from our new map and store it. + _objRefList = new List(); + foreach (var refNode in referenceNodes) + { + string paramName = refNode.GetReferenceParamString(); + + if ((refNode.Reference == null) && (paramName == null)) + { + // This can't happen - if the ref is null it must be because it's a named param + throw new Exception("Reference and paramName can't both be null"); + } + + if (paramName == null) + { + paramName = _compObjToParamNameMap[refNode.Reference]; + } + + _objRefList.Add(new ReferenceInfo(paramName, refNode.Reference)); + refNode.ParamName = paramName; + } + } + + // Generates Excel-column-like identifiers, e.g. A, B, ..., Z, AA, BA... + // This implementation aggregates characters in reverse order to avoid having to + // precompute the exact number of characters in the resulting string. This is not + // important in this context as the only critical property to maintain is to have + // a unique mapping to each input value to the resulting sequence of letters. + //[System.Runtime.CompilerServices.SkipLocalsInit] + static unsafe string CreateUniqueParamNameFromIndex(uint i) + { + const int alphabetLength = 'Z' - 'A' + 1; + + // The total length of the resulting sequence is guaranteed to always + // be less than 8, given that log26(4294967295) ≈ 6.8. In this case we + // are just allocating the immediate next power of two following that. + // Note: this is using a char* buffer instead of Span as the latter + // is not referenced here, and we don't want to pull in an extra package. + char* characters = stackalloc char[8]; + + characters[0] = (char)('A' + (i % alphabetLength)); + + int totalCharacters = 1; + + while ((i /= alphabetLength) > 0) + { + i--; + + characters[totalCharacters++] = (char)('A' + (i % alphabetLength)); + } + + return new string(characters, 0, totalCharacters); + } + } + + /// + /// Sets all parameters. + /// + /// The animation. + internal void SetAllParameters(CompositionAnimation animation) + { + // Make sure the list is populated + EnsureReferenceInfo(); + + foreach (var refInfo in _objRefList) + { + animation.SetReferenceParameter(refInfo.ParameterName, refInfo.CompObject); + } + + foreach (var constParam in _constParamMap) + { + if (constParam.Value.GetType() == typeof(bool)) + { + animation.SetBooleanParameter(constParam.Key, (bool)constParam.Value); + } + else if (constParam.Value.GetType() == typeof(float)) + { + animation.SetScalarParameter(constParam.Key, (float)constParam.Value); + } + else if (constParam.Value.GetType() == typeof(Vector2)) + { + animation.SetVector2Parameter(constParam.Key, (Vector2)constParam.Value); + } + else if (constParam.Value.GetType() == typeof(Vector3)) + { + animation.SetVector3Parameter(constParam.Key, (Vector3)constParam.Value); + } + else if (constParam.Value.GetType() == typeof(Vector4)) + { + animation.SetVector4Parameter(constParam.Key, (Vector4)constParam.Value); + } + else if (constParam.Value.GetType() == typeof(Color)) + { + animation.SetColorParameter(constParam.Key, (Color)constParam.Value); + } + else if (constParam.Value.GetType() == typeof(Quaternion)) + { + animation.SetQuaternionParameter(constParam.Key, (Quaternion)constParam.Value); + } + else if (constParam.Value.GetType() == typeof(Matrix3x2)) + { + animation.SetMatrix3x2Parameter(constParam.Key, (Matrix3x2)constParam.Value); + } + else if (constParam.Value.GetType() == typeof(Matrix4x4)) + { + animation.SetMatrix4x4Parameter(constParam.Key, (Matrix4x4)constParam.Value); + } + else + { + throw new Exception($"Unexpected constant parameter datatype ({constParam.Value.GetType()})"); + } + } + } + + /// + /// Gets the value. + /// + /// System.String. + protected internal abstract string GetValue(); + + /// + /// Subchannelses the internal. + /// + /// A class that derives from ExpressionNode. + /// The subchannels. + /// T. + protected internal T SubchannelsInternal(params string[] subchannels) + where T : ExpressionNode + { + ExpressionNodeType swizzleNodeType = ExpressionNodeType.Swizzle; + T newNode; + + switch (subchannels.GetLength(0)) + { + case 1: + newNode = ExpressionFunctions.Function(swizzleNodeType, this) as T; + break; + + case 2: + newNode = ExpressionFunctions.Function(swizzleNodeType, this) as T; + break; + + case 3: + newNode = ExpressionFunctions.Function(swizzleNodeType, this) as T; + break; + + case 4: + newNode = ExpressionFunctions.Function(swizzleNodeType, this) as T; + break; + + case 6: + newNode = ExpressionFunctions.Function(swizzleNodeType, this) as T; + break; + + case 16: + newNode = ExpressionFunctions.Function(swizzleNodeType, this) as T; + break; + + default: + throw new Exception($"Invalid subchannel count ({subchannels.GetLength(0)})"); + } + + (newNode as ExpressionNode).Subchannels = subchannels; + + return newNode; + } + + /// + /// Populates the parameter nodes. + /// + /// The constant parameter map. + /// The reference nodes. + protected internal void PopulateParameterNodes(ref Dictionary constParamMap, ref HashSet referenceNodes) + { + var refNode = this as ReferenceNode; + if ((refNode != null) && (refNode.NodeType != ExpressionNodeType.TargetReference)) + { + referenceNodes.Add(refNode); + } + + if ((_constParamMap != null) && (_constParamMap != constParamMap)) + { + foreach (var entry in _constParamMap) + { + // If this parameter hasn't already been set on the root, use this node's parameter info + if (!constParamMap.ContainsKey(entry.Key)) + { + constParamMap[entry.Key] = entry.Value; + } + } + } + + foreach (var child in Children) + { + child.PopulateParameterNodes(ref constParamMap, ref referenceNodes); + } + } + + private OperationType GetOperationKind() + { + return ExpressionFunctions.GetNodeInfoFromType(NodeType).NodeOperationKind; + } + + private string GetOperationString() + { + return ExpressionFunctions.GetNodeInfoFromType(NodeType).OperationString; + } + + private string ToExpressionStringInternal() + { + string ret; + + // Do a recursive depth-first traversal of the node tree to print out the full expression string + switch (GetOperationKind()) + { + case OperationType.Function: + if (Children.Count == 0) + { + throw new Exception("Can't have an expression function with no params"); + } + + ret = $"{GetOperationString()}({Children[0].ToExpressionStringInternal()}"; + for (int i = 1; i < Children.Count; i++) + { + ret += "," + Children[i].ToExpressionStringInternal(); + } + + ret += ")"; + break; + + case OperationType.Operator: + if (Children.Count != 2) + { + throw new Exception("Can't have an operator that doesn't have 2 exactly params"); + } + + ret = $"({Children[0].ToExpressionStringInternal()} {GetOperationString()} {Children[1].ToExpressionStringInternal()})"; + break; + + case OperationType.UnaryOperator: + if (Children.Count != 1) + { + throw new Exception("Can't have an unary operator that doesn't have exactly one params"); + } + + ret = $"( {GetOperationString()} {Children[0].ToExpressionStringInternal()} )"; + break; + + case OperationType.Constant: + if (Children.Count == 0) + { + // If a parameterName was specified, use it. Otherwise write the value. + ret = ParamName ?? GetValue(); + } + else + { + throw new Exception("Constants must have 0 children"); + } + + break; + + case OperationType.Swizzle: + if (Children.Count != 1) + { + throw new Exception("Swizzles should have exactly 1 child"); + } + + string swizzleString = string.Empty; + foreach (var sub in Subchannels) + { + swizzleString += sub; + } + + ret = $"{Children[0].ToExpressionStringInternal()}.{swizzleString}"; + break; + + case OperationType.Reference: + if ((NodeType == ExpressionNodeType.Reference) || + (NodeType == ExpressionNodeType.TargetReference)) + { + // This is the reference node itself + if (Children.Count != 0) + { + throw new Exception("References cannot have children"); + } + + ret = (this as ReferenceNode).GetReferenceParamString(); + } + else if (NodeType == ExpressionNodeType.ReferenceProperty) + { + // This is the property node of the reference + if (Children.Count != 1) + { + throw new Exception("Reference properties must have exactly one child"); + } + + if (PropertyName == null) + { + throw new Exception("Reference properties must have a property name"); + } + + ret = $"{Children[0].ToExpressionStringInternal()}.{PropertyName}"; + } + else if (NodeType == ExpressionNodeType.StartingValueProperty) + { + // This is a "this.StartingValue" node + if (Children.Count != 0) + { + throw new Exception("StartingValue references Cannot have children"); + } + + ret = "this.StartingValue"; + } + else if (NodeType == ExpressionNodeType.CurrentValueProperty) + { + // This is a "this.CurrentValue" node + if (Children.Count != 0) + { + throw new Exception("CurrentValue references Cannot have children"); + } + + ret = "this.CurrentValue"; + } + else + { + throw new Exception("Unexpected NodeType for OperationType.Reference"); + } + + break; + + case OperationType.Conditional: + if (Children.Count != 3) + { + throw new Exception("Conditionals must have exactly 3 children"); + } + + ret = $"(({Children[0].ToExpressionStringInternal()}) ? ({Children[1].ToExpressionStringInternal()}) : ({Children[2].ToExpressionStringInternal()}))"; + break; + + default: + throw new Exception($"Unexpected operation type ({GetOperationKind()}), nodeType = {NodeType}"); + } + + return ret; + } + + /// + /// Struct ReferenceInfo + /// + internal struct ReferenceInfo + { + /// + /// Initializes a new instance of the struct. + /// + /// Name of the parameter. + /// The comp object. + public ReferenceInfo(string paramName, CompositionObject compObj) + { + ParameterName = paramName; + CompObject = compObj; + } + + /// + /// Gets or sets the name of the parameter. + /// + /// The name of the parameter. + public string ParameterName { get; set; } + + /// + /// Gets or sets the comp object. + /// + /// The comp object. + public CompositionObject CompObject { get; set; } + } + + /// + /// Gets or sets the name of the property. + /// + /// The name of the property. + internal string PropertyName { get; set; } + + /// + /// Gets or sets the type of the node. + /// + /// The type of the node. + internal ExpressionNodeType NodeType { get; set; } + + /// + /// Gets or sets the children. + /// + /// The children. + internal List Children { get; set; } = new List(); + + /// + /// Gets or sets the name of the parameter. + /// + /// The name of the parameter. + internal string ParamName { get; set; } + + /// + /// Gets or sets the expression animation. + /// + /// The expression animation. + internal ExpressionAnimation ExpressionAnimation { get; set; } + + /// + /// Gets or sets the subchannels. + /// + /// The subchannels. + protected internal string[] Subchannels { get; set; } + } +} diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/ExpressionNodeType.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/ExpressionNodeType.cs new file mode 100644 index 000000000..44089ce2b --- /dev/null +++ b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/ExpressionNodeType.cs @@ -0,0 +1,387 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork +{ + /// + /// Enum ExpressionNodeType + /// + internal enum ExpressionNodeType + { + /// + /// The constant value + /// + ConstantValue, + + /// + /// The constant parameter + /// + ConstantParameter, + + /// + /// The current value property + /// + CurrentValueProperty, + + /// + /// The reference + /// + Reference, + + /// + /// The reference property + /// + ReferenceProperty, + + /// + /// The starting value property + /// + StartingValueProperty, + + /// + /// The target reference + /// + TargetReference, + + /// + /// The conditional + /// + Conditional, + + /// + /// The swizzle + /// + Swizzle, + + /// + /// The add + /// + Add, + + /// + /// The and + /// + And, + + /// + /// The divide + /// + Divide, + + /// + /// The equals + /// + Equals, + + /// + /// The greater than + /// + GreaterThan, + + /// + /// The greater than equals + /// + GreaterThanEquals, + + /// + /// The less than + /// + LessThan, + + /// + /// The less than equals + /// + LessThanEquals, + + /// + /// The multiply + /// + Multiply, + + /// + /// The not + /// + Not, + + /// + /// The not equals + /// + NotEquals, + + /// + /// The or + /// + Or, + + /// + /// The subtract + /// + Subtract, + + /// + /// The absolute + /// + Absolute, + + /// + /// The acos + /// + Acos, + + /// + /// The asin + /// + Asin, + + /// + /// The atan + /// + Atan, + + /// + /// The cos + /// + Cos, + + /// + /// The ceil + /// + Ceil, + + /// + /// The clamp + /// + Clamp, + + /// + /// The color HSL + /// + ColorHsl, + + /// + /// The color RGB + /// + ColorRgb, + + /// + /// The color lerp + /// + ColorLerp, + + /// + /// The color lerp HSL + /// + ColorLerpHsl, + + /// + /// The color lerp RGB + /// + ColorLerpRgb, + + /// + /// The concatenate + /// + Concatenate, + + /// + /// The distance + /// + Distance, + + /// + /// The distance squared + /// + DistanceSquared, + + /// + /// The floor + /// + Floor, + + /// + /// The inverse + /// + Inverse, + + /// + /// The length + /// + Length, + + /// + /// The length squared + /// + LengthSquared, + + /// + /// The lerp + /// + Lerp, + + /// + /// The ln + /// + Ln, + + /// + /// The log10 + /// + Log10, + + /// + /// The maximum + /// + Max, + + /// + /// The matrix3x2 from rotation + /// + Matrix3x2FromRotation, + + /// + /// The matrix3x2 from scale + /// + Matrix3x2FromScale, + + /// + /// The matrix3x2 from skew + /// + Matrix3x2FromSkew, + + /// + /// The matrix3x2 from translation + /// + Matrix3x2FromTranslation, + + /// + /// The matrix3x2 + /// + Matrix3x2, + + /// + /// The matrix4x4 from axis angle + /// + Matrix4x4FromAxisAngle, + + /// + /// The matrix4x4 from scale + /// + Matrix4x4FromScale, + + /// + /// The matrix4x4 from translation + /// + Matrix4x4FromTranslation, + + /// + /// The matrix4x4 + /// + Matrix4x4, + + /// + /// The minimum + /// + Min, + + /// + /// The modulus + /// + Modulus, + + /// + /// The negate + /// + Negate, + + /// + /// The normalize + /// + Normalize, + + /// + /// The pow + /// + Pow, + + /// + /// The quaternion from axis angle + /// + QuaternionFromAxisAngle, + + /// + /// The quaternion + /// + Quaternion, + + /// + /// The round + /// + Round, + + /// + /// The scale + /// + Scale, + + /// + /// The sin + /// + Sin, + + /// + /// The slerp + /// + Slerp, + + /// + /// The SQRT + /// + Sqrt, + + /// + /// The square + /// + Square, + + /// + /// The tan + /// + Tan, + + /// + /// To degrees + /// + ToDegrees, + + /// + /// To radians + /// + ToRadians, + + /// + /// The transform + /// + Transform, + + /// + /// The vector2 + /// + Vector2, + + /// + /// The vector3 + /// + Vector3, + + /// + /// The vector4 + /// + Vector4, + + /// + /// The count + /// + Count + } +} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Matrix3x2Node.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Matrix3x2Node.cs new file mode 100644 index 000000000..28b964da4 --- /dev/null +++ b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Matrix3x2Node.cs @@ -0,0 +1,393 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Numerics; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork +{ + // Ignore warning: 'Matrix3x2Node' defines operator == or operator != but does not override Object.Equals(object o) && Object.GetHashCode() +#pragma warning disable CS0660, CS0661 + + /// + /// Class Matrix3x2Node. This class cannot be inherited. + /// + /// + public sealed class Matrix3x2Node : ExpressionNode + { + /// + /// Initializes a new instance of the class. + /// + internal Matrix3x2Node() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The value. + internal Matrix3x2Node(Matrix3x2 value) + { + _value = value; + NodeType = ExpressionNodeType.ConstantValue; + } + + /// + /// Initializes a new instance of the class. + /// + /// Name of the parameter. + internal Matrix3x2Node(string paramName) + { + ParamName = paramName; + NodeType = ExpressionNodeType.ConstantParameter; + } + + /// + /// Initializes a new instance of the class. + /// + /// Name of the parameter. + /// The value. + internal Matrix3x2Node(string paramName, Matrix3x2 value) + { + ParamName = paramName; + _value = value; + NodeType = ExpressionNodeType.ConstantParameter; + + SetMatrix3x2Parameter(paramName, value); + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value. + /// The result of the conversion. + public static implicit operator Matrix3x2Node(Matrix3x2 value) + { + return new Matrix3x2Node(value); + } + + /// + /// Implements the + operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static Matrix3x2Node operator +(Matrix3x2Node left, Matrix3x2Node right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Add, left, right); + } + + /// + /// Implements the - operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static Matrix3x2Node operator -(Matrix3x2Node left, Matrix3x2Node right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Subtract, left, right); + } + + /// + /// Implements the - operator. + /// + /// The value. + /// The result of the operator. + public static Matrix3x2Node operator -(Matrix3x2Node value) + { + return ExpressionFunctions.Function(ExpressionNodeType.Negate, value); + } + + /// + /// Implements the * operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static Matrix3x2Node operator *(Matrix3x2Node left, ScalarNode right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); + } + + /// + /// Implements the * operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static Matrix3x2Node operator *(Matrix3x2Node left, Matrix3x2Node right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); + } + + /// + /// Implements the == operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static BooleanNode operator ==(Matrix3x2Node left, Matrix3x2Node right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Equals, left, right); + } + + /// + /// Implements the != operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static BooleanNode operator !=(Matrix3x2Node left, Matrix3x2Node right) + { + return ExpressionFunctions.Function(ExpressionNodeType.NotEquals, left, right); + } + + /// + /// Enum Subchannel + /// + public enum Subchannel + { + /// + /// The channel11 + /// + Channel11, + + /// + /// The channel12 + /// + Channel12, + + /// + /// The channel21 + /// + Channel21, + + /// + /// The channel22 + /// + Channel22, + + /// + /// The channel31 + /// + Channel31, + + /// + /// The channel32 + /// + Channel32, + } + + /// + /// Gets the channel11. + /// + /// The channel11. + public ScalarNode Channel11 + { + get { return GetSubchannels(Subchannel.Channel11); } + } + + /// + /// Gets the channel12. + /// + /// The channel12. + public ScalarNode Channel12 + { + get { return GetSubchannels(Subchannel.Channel12); } + } + + /// + /// Gets the channel21. + /// + /// The channel21. + public ScalarNode Channel21 + { + get { return GetSubchannels(Subchannel.Channel21); } + } + + /// + /// Gets the channel22. + /// + /// The channel22. + public ScalarNode Channel22 + { + get { return GetSubchannels(Subchannel.Channel22); } + } + + /// + /// Gets the channel31. + /// + /// The channel31. + public ScalarNode Channel31 + { + get { return GetSubchannels(Subchannel.Channel31); } + } + + /// + /// Gets the channel32. + /// + /// The channel32. + public ScalarNode Channel32 + { + get { return GetSubchannels(Subchannel.Channel32); } + } + + /// + /// Create a new type by re-arranging the Matrix subchannels. + /// + /// The subchannel. + /// ScalarNode + public ScalarNode GetSubchannels(Subchannel s) + { + return SubchannelsInternal(s.ToString()); + } + + /// + /// Create a new type by re-arranging the Matrix subchannels. + /// + /// The first subchannel. + /// The second subchannel. + /// Vector2Node + public Vector2Node GetSubchannels(Subchannel s1, Subchannel s2) + { + return SubchannelsInternal(s1.ToString(), s2.ToString()); + } + + /// + /// Create a new type by re-arranging the Matrix subchannels. + /// + /// The first subchannel. + /// The second subchannel. + /// The third subchannel. + /// Vector3Node + public Vector3Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3) + { + return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString()); + } + + /// + /// Create a new type by re-arranging the Matrix subchannels. + /// + /// The first subchannel. + /// The second subchannel. + /// The third subchannel. + /// The fourth subchannel. + /// Vector4Node + public Vector4Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4) + { + return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString()); + } + + /// + /// Create a new type by re-arranging the Matrix subchannels. + /// + /// The first subchannel. + /// The second subchannel. + /// The third subchannel. + /// The fourth subchannel. + /// The fifth subchannel. + /// The sixth subchannel. + /// Matrix3x2Node + public Matrix3x2Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4, Subchannel s5, Subchannel s6) + { + return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString(), s5.ToString(), s6.ToString()); + } + + /// + /// Create a new type by re-arranging the Matrix subchannels. + /// + /// The first subchannel. + /// The second subchannel. + /// The third subchannel. + /// The fourth subchannel. + /// The fifth subchannel. + /// The sixth subchannel. + /// The seventh subchannel. + /// The eighth subchannel. + /// The ninth subchannel. + /// The tenth subchannel. + /// The eleventh subchannel. + /// The twelfth subchannel. + /// The thirteenth subchannel. + /// The fourteenth subchannel. + /// The fifteenth subchannel. + /// The sixteenth subchannel. + /// Matrix4x4Node +#pragma warning disable SA1117 // Parameters must be on same line or separate lines + public Matrix4x4Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4, + Subchannel s5, Subchannel s6, Subchannel s7, Subchannel s8, + Subchannel s9, Subchannel s10, Subchannel s11, Subchannel s12, + Subchannel s13, Subchannel s14, Subchannel s15, Subchannel s16) + { + return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString(), + s5.ToString(), s6.ToString(), s7.ToString(), s8.ToString(), + s9.ToString(), s10.ToString(), s11.ToString(), s12.ToString(), + s13.ToString(), s14.ToString(), s15.ToString(), s16.ToString()); + } +#pragma warning restore SA1117 // Parameters must be on same line or separate lines + + /// + /// Gets the value. + /// + /// System.String. + protected internal override string GetValue() + { + return $"Matrix3x2({_value.M11.ToCompositionString()},{_value.M12.ToCompositionString()},{_value.M21.ToCompositionString()},{_value.M22.ToCompositionString()},{_value.M31.ToCompositionString()},{_value.M32.ToCompositionString()})"; + } + + private Matrix3x2 _value; + + /// + /// Evaluates the current value of the expression + /// + /// The current value of the expression + public Matrix3x2 Evaluate() + { + switch (NodeType) + { + case ExpressionNodeType.ConstantValue: + return _value; + case ExpressionNodeType.ReferenceProperty: + var reference = (Children[0] as ReferenceNode).Reference; + reference.Properties.TryGetMatrix3x2(PropertyName, out var referencedProperty); + return referencedProperty; + case ExpressionNodeType.Add: + return + (Children[0] as Matrix3x2Node).Evaluate() + + (Children[1] as Matrix3x2Node).Evaluate(); + case ExpressionNodeType.Subtract: + return + (Children[0] as Matrix3x2Node).Evaluate() - + (Children[1] as Matrix3x2Node).Evaluate(); + case ExpressionNodeType.Negate: + return + -(Children[0] as Matrix3x2Node).Evaluate(); + case ExpressionNodeType.Multiply: + return (Children[0], Children[1]) switch + { + (Matrix3x2Node v1, Matrix3x2Node v2) => v1.Evaluate() * v2.Evaluate(), + (Matrix3x2Node v1, ScalarNode s2) => v1.Evaluate() * s2.Evaluate(), + (ScalarNode s1, Matrix3x2Node v2) => v2.Evaluate() * s1.Evaluate(), + _ => throw new NotImplementedException() + }; + case ExpressionNodeType.Conditional: + return + (Children[0] as BooleanNode).Evaluate() ? + (Children[1] as Matrix3x2Node).Evaluate() : + (Children[2] as Matrix3x2Node).Evaluate(); + case ExpressionNodeType.Swizzle: + return new Matrix3x2( + Children[0].EvaluateSubchannel(Subchannels[0]), + Children[0].EvaluateSubchannel(Subchannels[1]), + Children[0].EvaluateSubchannel(Subchannels[2]), + Children[0].EvaluateSubchannel(Subchannels[3]), + Children[0].EvaluateSubchannel(Subchannels[4]), + Children[0].EvaluateSubchannel(Subchannels[5])); + default: + throw new NotImplementedException(); + } + } + } +#pragma warning restore CS0660, CS0661 +} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Matrix4x4Node.Subchannel.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Matrix4x4Node.Subchannel.cs new file mode 100644 index 000000000..f76f4ce42 --- /dev/null +++ b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Matrix4x4Node.Subchannel.cs @@ -0,0 +1,99 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork +{ + /// + /// Class Matrix4x4Node. This class cannot be inherited. + /// + /// + public sealed partial class Matrix4x4Node : ExpressionNode + { + /// + /// Enum Subchannel + /// + public enum Subchannel + { + /// + /// The channel11 + /// + Channel11, + + /// + /// The channel12 + /// + Channel12, + + /// + /// The channel13 + /// + Channel13, + + /// + /// The channel14 + /// + Channel14, + + /// + /// The channel21 + /// + Channel21, + + /// + /// The channel22 + /// + Channel22, + + /// + /// The channel23 + /// + Channel23, + + /// + /// The channel24 + /// + Channel24, + + /// + /// The channel31 + /// + Channel31, + + /// + /// The channel32 + /// + Channel32, + + /// + /// The channel33 + /// + Channel33, + + /// + /// The channel34 + /// + Channel34, + + /// + /// The channel41 + /// + Channel41, + + /// + /// The channel42 + /// + Channel42, + + /// + /// The channel43 + /// + Channel43, + + /// + /// The channel44 + /// + Channel44, + } + } +} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Matrix4x4Node.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Matrix4x4Node.cs new file mode 100644 index 000000000..818648a76 --- /dev/null +++ b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Matrix4x4Node.cs @@ -0,0 +1,488 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Numerics; +using Windows.UI.Composition; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork +{ + // Ignore warning: 'Matrix4x4Node' defines operator == or operator != but does not override Object.Equals(object o) && Object.GetHashCode() +#pragma warning disable CS0660, CS0661 + /// + /// Class Matrix4x4Node. This class cannot be inherited. + /// + /// + public sealed partial class Matrix4x4Node : ExpressionNode + { + /// + /// Initializes a new instance of the class. + /// + internal Matrix4x4Node() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The value. + internal Matrix4x4Node(Matrix4x4 value) + { + _value = value; + NodeType = ExpressionNodeType.ConstantValue; + } + + /// + /// Initializes a new instance of the class. + /// + /// Name of the parameter. + internal Matrix4x4Node(string paramName) + { + ParamName = paramName; + NodeType = ExpressionNodeType.ConstantParameter; + } + + /// + /// Initializes a new instance of the class. + /// + /// Name of the parameter. + /// The value. + internal Matrix4x4Node(string paramName, Matrix4x4 value) + { + ParamName = paramName; + _value = value; + NodeType = ExpressionNodeType.ConstantParameter; + + SetMatrix4x4Parameter(paramName, value); + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value. + /// The result of the conversion. + public static implicit operator Matrix4x4Node(Matrix4x4 value) + { + return new Matrix4x4Node(value); + } + + /// + /// Implements the + operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static Matrix4x4Node operator +(Matrix4x4Node left, Matrix4x4Node right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Add, left, right); + } + + /// + /// Implements the - operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static Matrix4x4Node operator -(Matrix4x4Node left, Matrix4x4Node right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Subtract, left, right); + } + + /// + /// Implements the - operator. + /// + /// The value. + /// The result of the operator. + public static Matrix4x4Node operator -(Matrix4x4Node value) + { + return ExpressionFunctions.Function(ExpressionNodeType.Negate, value); + } + + /// + /// Implements the * operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static Matrix4x4Node operator *(Matrix4x4Node left, ScalarNode right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); + } + + /// + /// Implements the * operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static Matrix4x4Node operator *(Matrix4x4Node left, Matrix4x4Node right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); + } + + /// + /// Implements the == operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static BooleanNode operator ==(Matrix4x4Node left, Matrix4x4Node right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Equals, left, right); + } + + /// + /// Implements the != operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static BooleanNode operator !=(Matrix4x4Node left, Matrix4x4Node right) + { + return ExpressionFunctions.Function(ExpressionNodeType.NotEquals, left, right); + } + + /// + /// Gets the channel11. + /// + /// The channel11. + public ScalarNode Channel11 + { + get { return GetSubchannels(Subchannel.Channel11); } + } + + /// + /// Gets the channel12. + /// + /// The channel12. + public ScalarNode Channel12 + { + get { return GetSubchannels(Subchannel.Channel12); } + } + + /// + /// Gets the channel13. + /// + /// The channel13. + public ScalarNode Channel13 + { + get { return GetSubchannels(Subchannel.Channel13); } + } + + /// + /// Gets the channel14. + /// + /// The channel14. + public ScalarNode Channel14 + { + get { return GetSubchannels(Subchannel.Channel14); } + } + + /// + /// Gets the channel21. + /// + /// The channel21. + public ScalarNode Channel21 + { + get { return GetSubchannels(Subchannel.Channel21); } + } + + /// + /// Gets the channel22. + /// + /// The channel22. + public ScalarNode Channel22 + { + get { return GetSubchannels(Subchannel.Channel22); } + } + + /// + /// Gets the channel23. + /// + /// The channel23. + public ScalarNode Channel23 + { + get { return GetSubchannels(Subchannel.Channel23); } + } + + /// + /// Gets the channel24. + /// + /// The channel24. + public ScalarNode Channel24 + { + get { return GetSubchannels(Subchannel.Channel24); } + } + + /// + /// Gets the channel31. + /// + /// The channel31. + public ScalarNode Channel31 + { + get { return GetSubchannels(Subchannel.Channel31); } + } + + /// + /// Gets the channel32. + /// + /// The channel32. + public ScalarNode Channel32 + { + get { return GetSubchannels(Subchannel.Channel32); } + } + + /// + /// Gets the channel33. + /// + /// The channel33. + public ScalarNode Channel33 + { + get { return GetSubchannels(Subchannel.Channel33); } + } + + /// + /// Gets the channel34. + /// + /// The channel34. + public ScalarNode Channel34 + { + get { return GetSubchannels(Subchannel.Channel34); } + } + + /// + /// Gets the channel41. + /// + /// The channel41. + public ScalarNode Channel41 + { + get { return GetSubchannels(Subchannel.Channel41); } + } + + /// + /// Gets the channel42. + /// + /// The channel42. + public ScalarNode Channel42 + { + get { return GetSubchannels(Subchannel.Channel42); } + } + + /// + /// Gets the channel43. + /// + /// The channel43. + public ScalarNode Channel43 + { + get { return GetSubchannels(Subchannel.Channel43); } + } + + /// + /// Gets the channel44. + /// + /// The channel44. + public ScalarNode Channel44 + { + get { return GetSubchannels(Subchannel.Channel44); } + } + + /// + /// Gets the channel11 channel22 channel33. + /// + /// The channel11 channel22 channel33. + public Vector3Node Channel11Channel22Channel33 + { + get { return GetSubchannels(Subchannel.Channel11, Subchannel.Channel22, Subchannel.Channel33); } + } + + /// + /// Gets the channel41 channel42 channel43. + /// + /// The channel41 channel42 channel43. + public Vector3Node Channel41Channel42Channel43 + { + get { return GetSubchannels(Subchannel.Channel41, Subchannel.Channel42, Subchannel.Channel43); } + } + + /// + /// Create a new type by re-arranging the Matrix subchannels. + /// + /// The s. + /// ScalarNode. + public ScalarNode GetSubchannels(Subchannel s) + { + return SubchannelsInternal(s.ToString()); + } + + /// + /// Create a new type by re-arranging the Matrix subchannels. + /// + /// The first subchannel. + /// The second subchannel. + /// Vector2Node + public Vector2Node GetSubchannels(Subchannel s1, Subchannel s2) + { + return SubchannelsInternal(s1.ToString(), s2.ToString()); + } + + /// + /// Create a new type by re-arranging the Matrix subchannels. + /// + /// The first subchannel. + /// The second subchannel. + /// The third subchannel. + /// Vector3Node + public Vector3Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3) + { + return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString()); + } + + /// + /// Create a new type by re-arranging the Matrix subchannels. + /// + /// The first subchannel. + /// The second subchannel. + /// The third subchannel. + /// The fourth subchannel. + /// Vector4Node + public Vector4Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4) + { + return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString()); + } + + /// + /// Create a new type by re-arranging the Matrix subchannels. + /// + /// The first subchannel. + /// The second subchannel. + /// The third subchannel. + /// The fourth subchannel. + /// The fifth subchannel. + /// The sixth subchannel. + /// Matrix3x2Node + public Matrix3x2Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4, Subchannel s5, Subchannel s6) + { + return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString(), s5.ToString(), s6.ToString()); + } + + /// + /// Create a new type by re-arranging the Matrix subchannels. + /// + /// The first subchannel. + /// The second subchannel. + /// The third subchannel. + /// The fourth subchannel. + /// The fifth subchannel. + /// The sixth subchannel. + /// The seventh subchannel. + /// The eighth subchannel. + /// The ninth subchannel. + /// The tenth subchannel. + /// The eleventh subchannel. + /// The twelfth subchannel. + /// The thirteenth subchannel. + /// The fourteenth subchannel. + /// The fifteenth subchannel. + /// The sixteenth subchannel. + /// Matrix4x4Node +#pragma warning disable SA1117 // Parameters must be on same line or separate lines + public Matrix4x4Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4, + Subchannel s5, Subchannel s6, Subchannel s7, Subchannel s8, + Subchannel s9, Subchannel s10, Subchannel s11, Subchannel s12, + Subchannel s13, Subchannel s14, Subchannel s15, Subchannel s16) + { + return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString(), + s5.ToString(), s6.ToString(), s7.ToString(), s8.ToString(), + s9.ToString(), s10.ToString(), s11.ToString(), s12.ToString(), + s13.ToString(), s14.ToString(), s15.ToString(), s16.ToString()); + } +#pragma warning restore SA1117 // Parameters must be on same line or separate lines + + /// + /// Gets the value. + /// + /// System.String. + protected internal override string GetValue() + { + return $"Matrix4x4({_value.M11.ToCompositionString()},{_value.M12.ToCompositionString()},{_value.M13.ToCompositionString()},{_value.M14.ToCompositionString()}," + + $"{_value.M21.ToCompositionString()},{_value.M22.ToCompositionString()},{_value.M23.ToCompositionString()},{_value.M24.ToCompositionString()}," + + $"{_value.M31.ToCompositionString()},{_value.M32.ToCompositionString()},{_value.M33.ToCompositionString()},{_value.M34.ToCompositionString()}," + + $"{_value.M41.ToCompositionString()},{_value.M42.ToCompositionString()},{_value.M43.ToCompositionString()},{_value.M44.ToCompositionString()})"; + } + + private Matrix4x4 _value; + + /// + /// Evaluates the current value of the expression + /// + /// The current value of the expression + public Matrix4x4 Evaluate() + { + switch (NodeType) + { + case ExpressionNodeType.ConstantValue: + return _value; + case ExpressionNodeType.ReferenceProperty: + var reference = (Children[0] as ReferenceNode).Reference; + return PropertyName switch + { + nameof(Visual.TransformMatrix) => (reference as Visual).TransformMatrix, + _ => GetProperty() + }; + + Matrix4x4 GetProperty() + { + reference.Properties.TryGetMatrix4x4(PropertyName, out var value); + return value; + } + + case ExpressionNodeType.Add: + return + (Children[0] as Matrix4x4Node).Evaluate() + + (Children[1] as Matrix4x4Node).Evaluate(); + case ExpressionNodeType.Subtract: + return + (Children[0] as Matrix4x4Node).Evaluate() - + (Children[1] as Matrix4x4Node).Evaluate(); + case ExpressionNodeType.Negate: + return + -(Children[0] as Matrix4x4Node).Evaluate(); + case ExpressionNodeType.Multiply: + return (Children[0], Children[1]) switch + { + (Matrix4x4Node v1, Matrix4x4Node v2) => v1.Evaluate() * v2.Evaluate(), + (Matrix4x4Node v1, ScalarNode s2) => v1.Evaluate() * s2.Evaluate(), + (ScalarNode s1, Matrix4x4Node v2) => v2.Evaluate() * s1.Evaluate(), + _ => throw new NotImplementedException() + }; + case ExpressionNodeType.Conditional: + return + (Children[0] as BooleanNode).Evaluate() ? + (Children[1] as Matrix4x4Node).Evaluate() : + (Children[2] as Matrix4x4Node).Evaluate(); + case ExpressionNodeType.Swizzle: + return new Matrix4x4( + Children[0].EvaluateSubchannel(Subchannels[0]), + Children[0].EvaluateSubchannel(Subchannels[1]), + Children[0].EvaluateSubchannel(Subchannels[2]), + Children[0].EvaluateSubchannel(Subchannels[3]), + Children[0].EvaluateSubchannel(Subchannels[4]), + Children[0].EvaluateSubchannel(Subchannels[5]), + Children[0].EvaluateSubchannel(Subchannels[6]), + Children[0].EvaluateSubchannel(Subchannels[7]), + Children[0].EvaluateSubchannel(Subchannels[8]), + Children[0].EvaluateSubchannel(Subchannels[9]), + Children[0].EvaluateSubchannel(Subchannels[10]), + Children[0].EvaluateSubchannel(Subchannels[11]), + Children[0].EvaluateSubchannel(Subchannels[12]), + Children[0].EvaluateSubchannel(Subchannels[13]), + Children[0].EvaluateSubchannel(Subchannels[14]), + Children[0].EvaluateSubchannel(Subchannels[15])); + default: + throw new NotImplementedException(); + } + } + } +#pragma warning restore CS0660, CS0661 +} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/QuaternionNode.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/QuaternionNode.cs new file mode 100644 index 000000000..9289605a5 --- /dev/null +++ b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/QuaternionNode.cs @@ -0,0 +1,198 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Numerics; +using Windows.UI.Composition; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork +{ + // Ignore warning: 'QuaternionNode' defines operator == or operator != but does not override Object.Equals(object o) && Object.GetHashCode() +#pragma warning disable CS0660, CS0661 + /// + /// Class QuaternionNode. This class cannot be inherited. + /// + /// + public sealed class QuaternionNode : ExpressionNode + { + /// + /// Initializes a new instance of the class. + /// + internal QuaternionNode() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The value. + internal QuaternionNode(Quaternion value) + { + _value = value; + NodeType = ExpressionNodeType.ConstantValue; + } + + /// + /// Initializes a new instance of the class. + /// + /// Name of the parameter. + internal QuaternionNode(string paramName) + { + ParamName = paramName; + NodeType = ExpressionNodeType.ConstantParameter; + } + + /// + /// Initializes a new instance of the class. + /// + /// Name of the parameter. + /// The value. + internal QuaternionNode(string paramName, Quaternion value) + { + ParamName = paramName; + _value = value; + NodeType = ExpressionNodeType.ConstantParameter; + + SetQuaternionParameter(paramName, value); + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value. + /// The result of the conversion. + public static implicit operator QuaternionNode(Quaternion value) + { + return new QuaternionNode(value); + } + + /// + /// Implements the * operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static QuaternionNode operator *(QuaternionNode left, ScalarNode right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); + } + + /// + /// Implements the * operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static QuaternionNode operator *(QuaternionNode left, QuaternionNode right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); + } + + /// + /// Implements the / operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static QuaternionNode operator /(QuaternionNode left, QuaternionNode right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Divide, left, right); + } + + /// + /// Implements the == operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static BooleanNode operator ==(QuaternionNode left, QuaternionNode right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Equals, left, right); + } + + /// + /// Implements the != operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static BooleanNode operator !=(QuaternionNode left, QuaternionNode right) + { + return ExpressionFunctions.Function(ExpressionNodeType.NotEquals, left, right); + } + + /// + /// Gets the value. + /// + /// System.String. + protected internal override string GetValue() + { + return $"Quaternion({_value.X.ToCompositionString()},{_value.Y.ToCompositionString()},{_value.Z.ToCompositionString()},{_value.W.ToCompositionString()})"; + } + + private Quaternion _value; + + /// + /// Evaluates the current value of the expression + /// + /// The current value of the expression + public Quaternion Evaluate() + { + switch (NodeType) + { + case ExpressionNodeType.ConstantValue: + return _value; + case ExpressionNodeType.ReferenceProperty: + var reference = (Children[0] as ReferenceNode).Reference; + return PropertyName switch + { + nameof(Visual.Orientation) => (reference as Visual).Orientation, + _ => GetProperty() + }; + + Quaternion GetProperty() + { + reference.Properties.TryGetQuaternion(PropertyName, out var value); + return value; + } + + case ExpressionNodeType.Add: + return + (Children[0] as QuaternionNode).Evaluate() + + (Children[1] as QuaternionNode).Evaluate(); + case ExpressionNodeType.Subtract: + return + (Children[0] as QuaternionNode).Evaluate() - + (Children[1] as QuaternionNode).Evaluate(); + case ExpressionNodeType.Negate: + return + -(Children[0] as QuaternionNode).Evaluate(); + case ExpressionNodeType.Multiply: + return (Children[0], Children[1]) switch + { + (QuaternionNode v1, QuaternionNode v2) => v1.Evaluate() * v2.Evaluate(), + (QuaternionNode v1, ScalarNode s2) => v1.Evaluate() * s2.Evaluate(), + (ScalarNode s1, QuaternionNode v2) => v2.Evaluate() * s1.Evaluate(), + _ => throw new NotImplementedException() + }; + case ExpressionNodeType.Divide: + return + (Children[0] as QuaternionNode).Evaluate() / + (Children[1] as QuaternionNode).Evaluate(); + case ExpressionNodeType.QuaternionFromAxisAngle: + return Quaternion.CreateFromAxisAngle((Children[0] as Vector3Node).Evaluate(), (Children[1] as ScalarNode).Evaluate()); + case ExpressionNodeType.Conditional: + return + (Children[0] as BooleanNode).Evaluate() ? + (Children[1] as QuaternionNode).Evaluate() : + (Children[2] as QuaternionNode).Evaluate(); + case ExpressionNodeType.Swizzle: + return new Quaternion(this.EvaluateSubchannel(Subchannels[0]), this.EvaluateSubchannel(Subchannels[1]), this.EvaluateSubchannel(Subchannels[2]), this.EvaluateSubchannel(Subchannels[4])); + default: + throw new NotImplementedException(); + } + } + } +#pragma warning restore CS0660, CS0661 +} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/ScalarNode.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/ScalarNode.cs new file mode 100644 index 000000000..935930bef --- /dev/null +++ b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/ScalarNode.cs @@ -0,0 +1,385 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Numerics; +using Windows.UI.Composition; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork +{ + // Ignore warning: 'ScalarNode' defines operator == or operator != but does not override Object.Equals(object o) && Object.GetHashCode() +#pragma warning disable CS0660, CS0661 + /// + /// Class ScalarNode. This class cannot be inherited. + /// + /// + public sealed class ScalarNode : ExpressionNode + { + /// + /// Initializes a new instance of the class. + /// + internal ScalarNode() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The value. + internal ScalarNode(float value) + { + _value = value; + NodeType = ExpressionNodeType.ConstantValue; + } + + /// + /// Initializes a new instance of the class. + /// + /// Name of the parameter. + internal ScalarNode(string paramName) + { + ParamName = paramName; + NodeType = ExpressionNodeType.ConstantParameter; + } + + /// + /// Initializes a new instance of the class. + /// + /// Name of the parameter. + /// The value. + internal ScalarNode(string paramName, float value) + { + ParamName = paramName; + _value = value; + NodeType = ExpressionNodeType.ConstantParameter; + + SetScalarParameter(paramName, value); + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value. + /// The result of the conversion. + public static implicit operator ScalarNode(float value) + { + return new ScalarNode(value); + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value. + /// The result of the conversion. + public static implicit operator ScalarNode(int value) + { + return new ScalarNode((float)value); + } + + /// + /// Implements the + operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static ScalarNode operator +(ScalarNode left, ScalarNode right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Add, left, right); + } + + /// + /// Implements the - operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static ScalarNode operator -(ScalarNode left, ScalarNode right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Subtract, left, right); + } + + /// + /// Implements the - operator. + /// + /// The value. + /// The result of the operator. + public static ScalarNode operator -(ScalarNode value) + { + return ExpressionFunctions.Function(ExpressionNodeType.Negate, value); + } + + /// + /// Implements the * operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static ScalarNode operator *(ScalarNode left, ScalarNode right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); + } + + /// + /// Implements the * operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static Vector2Node operator *(ScalarNode left, Vector2Node right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); + } + + /// + /// Implements the * operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static Vector3Node operator *(ScalarNode left, Vector3Node right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); + } + + /// + /// Implements the * operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static Vector4Node operator *(ScalarNode left, Vector4Node right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); + } + + /// + /// Implements the * operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static Matrix4x4Node operator *(ScalarNode left, Matrix4x4Node right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); + } + + /// + /// Implements the / operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static ScalarNode operator /(ScalarNode left, ScalarNode right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Divide, left, right); + } + + /// + /// Implements the % operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static ScalarNode operator %(ScalarNode left, ScalarNode right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Modulus, left, right); + } + + /// + /// Implements the == operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static BooleanNode operator ==(ScalarNode left, ScalarNode right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Equals, left, right); + } + + /// + /// Implements the != operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static BooleanNode operator !=(ScalarNode left, ScalarNode right) + { + return ExpressionFunctions.Function(ExpressionNodeType.NotEquals, left, right); + } + + /// + /// Implements the <= operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static BooleanNode operator <=(ScalarNode left, ScalarNode right) + { + return ExpressionFunctions.Function(ExpressionNodeType.LessThanEquals, left, right); + } + + /// + /// Implements the < operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static BooleanNode operator <(ScalarNode left, ScalarNode right) + { + return ExpressionFunctions.Function(ExpressionNodeType.LessThan, left, right); + } + + /// + /// Implements the >= operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static BooleanNode operator >=(ScalarNode left, ScalarNode right) + { + return ExpressionFunctions.Function(ExpressionNodeType.GreaterThanEquals, left, right); + } + + /// + /// Implements the > operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static BooleanNode operator >(ScalarNode left, ScalarNode right) + { + return ExpressionFunctions.Function(ExpressionNodeType.GreaterThan, left, right); + } + + /// + /// Gets the value. + /// + /// System.String. + protected internal override string GetValue() + { + return _value.ToCompositionString(); + } + + private float _value; + + /// + /// Evaluates the current value of the expression + /// + /// The current value of the expression + public float Evaluate() + { + switch (NodeType) + { + case ExpressionNodeType.ConstantValue: + return _value; + case ExpressionNodeType.ReferenceProperty: + var reference = (Children[0] as ReferenceNode).Reference; + return PropertyName switch + { + nameof(Visual.Opacity) => (reference as Visual).Opacity, + nameof(Visual.RotationAngle) => (reference as Visual).RotationAngle, + nameof(InsetClip.BottomInset) => (reference as InsetClip).BottomInset, + nameof(InsetClip.LeftInset) => (reference as InsetClip).LeftInset, + nameof(InsetClip.RightInset) => (reference as InsetClip).RightInset, + nameof(InsetClip.TopInset) => (reference as InsetClip).TopInset, + _ => GetProperty() + }; + + float GetProperty() + { + reference.Properties.TryGetScalar(PropertyName, out var value); + return value; + } + + case ExpressionNodeType.Negate: + return -(Children[0] as ScalarNode).Evaluate(); + case ExpressionNodeType.Add: + return (Children[0] as ScalarNode).Evaluate() + (Children[1] as ScalarNode).Evaluate(); + case ExpressionNodeType.Subtract: + return (Children[0] as ScalarNode).Evaluate() - (Children[1] as ScalarNode).Evaluate(); + case ExpressionNodeType.Multiply: + return (Children[0] as ScalarNode).Evaluate() * (Children[1] as ScalarNode).Evaluate(); + case ExpressionNodeType.Divide: + return (Children[0] as ScalarNode).Evaluate() / (Children[1] as ScalarNode).Evaluate(); + case ExpressionNodeType.Min: + return MathF.Min((Children[0] as ScalarNode).Evaluate(), (Children[1] as ScalarNode).Evaluate()); + case ExpressionNodeType.Max: + return MathF.Max((Children[0] as ScalarNode).Evaluate(), (Children[1] as ScalarNode).Evaluate()); + case ExpressionNodeType.Absolute: + return MathF.Abs((Children[0] as ScalarNode).Evaluate()); + case ExpressionNodeType.Sin: + return MathF.Sin((Children[0] as ScalarNode).Evaluate()); + case ExpressionNodeType.Cos: + return MathF.Cos((Children[0] as ScalarNode).Evaluate()); + case ExpressionNodeType.Asin: + return MathF.Asin((Children[0] as ScalarNode).Evaluate()); + case ExpressionNodeType.Acos: + return MathF.Acos((Children[0] as ScalarNode).Evaluate()); + case ExpressionNodeType.Atan: + return MathF.Atan((Children[0] as ScalarNode).Evaluate()); + case ExpressionNodeType.Ceil: + return MathF.Ceiling((Children[0] as ScalarNode).Evaluate()); + case ExpressionNodeType.Floor: + return MathF.Floor((Children[0] as ScalarNode).Evaluate()); + case ExpressionNodeType.Ln: + return MathF.Log((Children[0] as ScalarNode).Evaluate()); + case ExpressionNodeType.Log10: + return MathF.Log10((Children[0] as ScalarNode).Evaluate()); + case ExpressionNodeType.Pow: + return MathF.Pow((Children[0] as ScalarNode).Evaluate(), (Children[1] as ScalarNode).Evaluate()); + case ExpressionNodeType.Round: + return MathF.Round((Children[0] as ScalarNode).Evaluate()); + case ExpressionNodeType.Square: + return MathF.Pow((Children[0] as ScalarNode).Evaluate(), 2); + case ExpressionNodeType.Sqrt: + return MathF.Sqrt((Children[0] as ScalarNode).Evaluate()); + case ExpressionNodeType.ToDegrees: + return 180 * (Children[0] as ScalarNode).Evaluate() / MathF.PI; + case ExpressionNodeType.ToRadians: + return MathF.PI * (Children[0] as ScalarNode).Evaluate() / 180; + case ExpressionNodeType.Modulus: + return (Children[0] as ScalarNode).Evaluate() % (Children[1] as ScalarNode).Evaluate(); + case ExpressionNodeType.Conditional: + return (Children[0] as BooleanNode).Evaluate() ? (Children[1] as ScalarNode).Evaluate() : (Children[2] as ScalarNode).Evaluate(); + case ExpressionNodeType.Distance: + return Vector2.Distance((Children[0] as Vector2Node).Evaluate(), (Children[1] as Vector2Node).Evaluate()); + case ExpressionNodeType.Lerp: + { + var start = (Children[0] as ScalarNode).Evaluate(); + var end = (Children[1] as ScalarNode).Evaluate(); + var progress = (Children[2] as ScalarNode).Evaluate(); + return start + (progress * (end - start)); + } + + case ExpressionNodeType.Swizzle: + return Children[0] switch + { + ScalarNode n => n.Evaluate(), + Vector2Node n => Subchannels[0] switch + { + "X" => n.Evaluate().X, + _ => n.Evaluate().Y, + }, + Vector3Node n => Subchannels[0] switch + { + "X" => n.Evaluate().X, + "Y" => n.Evaluate().Y, + _ => n.Evaluate().Z, + }, + Vector4Node n => Subchannels[0] switch + { + "X" => n.Evaluate().X, + "Y" => n.Evaluate().Y, + "Z" => n.Evaluate().Z, + _ => n.Evaluate().W, + }, + _ => throw new NotImplementedException() + }; + default: + throw new NotImplementedException(); + } + } + } +#pragma warning restore CS0660, CS0661 +} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/ValueKeywordKind.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/ValueKeywordKind.cs new file mode 100644 index 000000000..f27077d89 --- /dev/null +++ b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/ValueKeywordKind.cs @@ -0,0 +1,22 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork +{ + /// + /// Enum ValueKeywordKind + /// + internal enum ValueKeywordKind + { + /// + /// The current value + /// + CurrentValue, + + /// + /// The starting value + /// + StartingValue, + } +} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Vector2Node.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Vector2Node.cs new file mode 100644 index 000000000..0d186105b --- /dev/null +++ b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Vector2Node.cs @@ -0,0 +1,370 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Numerics; +using Windows.UI.Composition; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork +{ + // Ignore warning: 'Vector2Node' defines operator == or operator != but does not override Object.Equals(object o) && Object.GetHashCode() +#pragma warning disable CS0660, CS0661 + /// + /// Class Vector2Node. This class cannot be inherited. + /// + /// + public sealed class Vector2Node : ExpressionNode + { + /// + /// Initializes a new instance of the class. + /// + internal Vector2Node() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The value. + internal Vector2Node(Vector2 value) + { + _value = value; + NodeType = ExpressionNodeType.ConstantValue; + } + + /// + /// Initializes a new instance of the class. + /// + /// Name of the parameter. + internal Vector2Node(string paramName) + { + ParamName = paramName; + NodeType = ExpressionNodeType.ConstantParameter; + } + + /// + /// Initializes a new instance of the class. + /// + /// Name of the parameter. + /// The value. + internal Vector2Node(string paramName, Vector2 value) + { + ParamName = paramName; + _value = value; + NodeType = ExpressionNodeType.ConstantParameter; + + SetVector2Parameter(paramName, value); + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value. + /// The result of the conversion. + public static implicit operator Vector2Node(Vector2 value) + { + return new Vector2Node(value); + } + + /// + /// Implements the + operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static Vector2Node operator +(Vector2Node left, Vector2Node right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Add, left, right); + } + + /// + /// Implements the - operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static Vector2Node operator -(Vector2Node left, Vector2Node right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Subtract, left, right); + } + + /// + /// Implements the - operator. + /// + /// The value. + /// The result of the operator. + public static Vector2Node operator -(Vector2Node value) + { + return ExpressionFunctions.Function(ExpressionNodeType.Negate, value); + } + + /// + /// Implements the * operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static Vector2Node operator *(Vector2Node left, ScalarNode right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); + } + + /// + /// Implements the * operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static Vector2Node operator *(Vector2Node left, Vector2Node right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); + } + + /// + /// Implements the / operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static Vector2Node operator /(Vector2Node left, Vector2Node right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Divide, left, right); + } + + /// + /// Implements the % operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static Vector2Node operator %(Vector2Node left, Vector2Node right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Modulus, left, right); + } + + /// + /// Implements the == operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static BooleanNode operator ==(Vector2Node left, Vector2Node right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Equals, left, right); + } + + /// + /// Implements the != operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static BooleanNode operator !=(Vector2Node left, Vector2Node right) + { + return ExpressionFunctions.Function(ExpressionNodeType.NotEquals, left, right); + } + + /// + /// Enum Subchannel + /// + public enum Subchannel + { + /// + /// The x channel + /// + X, + + /// + /// The y channel + /// + Y + } + + /// + /// Gets the x subchannel. + /// + /// The x subchannel. + public ScalarNode X + { + get { return GetSubchannels(Subchannel.X); } + } + + /// + /// Gets the y subchannel. + /// + /// The y subchannel. + public ScalarNode Y + { + get { return GetSubchannels(Subchannel.Y); } + } + + /// + /// Create a new type by re-arranging the Vector subchannels. + /// + /// The subchannel + /// ScalarNode + public ScalarNode GetSubchannels(Subchannel s) + { + return SubchannelsInternal(s.ToString()); + } + + /// + /// Create a new type by re-arranging the Vector subchannels. + /// + /// The first subchannel. + /// The second subchannel. + /// Vector2Node. + public Vector2Node GetSubchannels(Subchannel s1, Subchannel s2) + { + return SubchannelsInternal(s1.ToString(), s2.ToString()); + } + + /// + /// Create a new type by re-arranging the Vector subchannels. + /// + /// The first subchannel. + /// The second subchannel. + /// The third subchannel. + /// Vector3Node + public Vector3Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3) + { + return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString()); + } + + /// + /// Create a new type by re-arranging the Vector subchannels. + /// + /// The first subchannel. + /// The second subchannel. + /// The third subchannel. + /// The fourth subchannel. + /// Vector4Node + public Vector4Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4) + { + return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString()); + } + + /// + /// Create a new type by re-arranging the Vector subchannels. + /// + /// The first subchannel. + /// The second subchannel. + /// The third subchannel. + /// The fourth subchannel. + /// The fifth subchannel. + /// The sixth subchannel. + /// Matrix3x2Node + public Matrix3x2Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4, Subchannel s5, Subchannel s6) + { + return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString(), s5.ToString(), s6.ToString()); + } + + /// + /// Create a new type by re-arranging the Vector subchannels. + /// + /// The first subchannel. + /// The second subchannel. + /// The third subchannel. + /// The fourth subchannel. + /// The fifth subchannel. + /// The sixth subchannel. + /// The seventh subchannel. + /// The eighth subchannel. + /// The ninth subchannel. + /// The tenth subchannel. + /// The eleventh subchannel. + /// The twelfth subchannel. + /// The thirteenth subchannel. + /// The fourteenth subchannel. + /// The fifteenth subchannel. + /// The sixteenth subchannel. + /// Matrix4x4Node +#pragma warning disable SA1117 // Parameters must be on same line or separate lines + public Matrix4x4Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4, + Subchannel s5, Subchannel s6, Subchannel s7, Subchannel s8, + Subchannel s9, Subchannel s10, Subchannel s11, Subchannel s12, + Subchannel s13, Subchannel s14, Subchannel s15, Subchannel s16) + { + return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString(), + s5.ToString(), s6.ToString(), s7.ToString(), s8.ToString(), + s9.ToString(), s10.ToString(), s11.ToString(), s12.ToString(), + s13.ToString(), s14.ToString(), s15.ToString(), s16.ToString()); + } +#pragma warning restore SA1117 // Parameters must be on same line or separate lines + + /// + /// Gets the value. + /// + /// System.String. + protected internal override string GetValue() + { + return $"Vector2({_value.X.ToCompositionString()},{_value.Y.ToCompositionString()})"; + } + + private Vector2 _value; + + /// + /// Evaluates the current value of the expression + /// + /// The current value of the expression + public Vector2 Evaluate() + { + switch (NodeType) + { + case ExpressionNodeType.ConstantValue: + return _value; + case ExpressionNodeType.ReferenceProperty: + var reference = (Children[0] as ReferenceNode).Reference; + return PropertyName switch + { + nameof(Visual.Size) => (reference as Visual).Size, + nameof(Visual.AnchorPoint) => (reference as Visual).AnchorPoint, + _ => GetProperty() + }; + + Vector2 GetProperty() + { + reference.Properties.TryGetVector2(PropertyName, out var value); + return value; + } + + case ExpressionNodeType.Conditional: + return + (Children[0] as BooleanNode).Evaluate() ? + (Children[1] as Vector2Node).Evaluate() : + (Children[2] as Vector2Node).Evaluate(); + case ExpressionNodeType.Add: + return + (Children[0] as Vector2Node).Evaluate() + + (Children[1] as Vector2Node).Evaluate(); + case ExpressionNodeType.Subtract: + return + (Children[0] as Vector2Node).Evaluate() - + (Children[1] as Vector2Node).Evaluate(); + case ExpressionNodeType.Negate: + return + -(Children[0] as Vector2Node).Evaluate(); + case ExpressionNodeType.Multiply: + return (Children[0], Children[1]) switch + { + (Vector2Node v1, Vector2Node v2) => v1.Evaluate() * v2.Evaluate(), + (Vector2Node v1, ScalarNode s2) => v1.Evaluate() * s2.Evaluate(), + (ScalarNode s1, Vector2Node v2) => s1.Evaluate() * v2.Evaluate(), + _ => throw new NotImplementedException() + }; + case ExpressionNodeType.Divide: + return + (Children[0] as Vector2Node).Evaluate() / + (Children[1] as Vector2Node).Evaluate(); + case ExpressionNodeType.Vector2: + return new Vector2((Children[0] as ScalarNode).Evaluate(), (Children[1] as ScalarNode).Evaluate()); + case ExpressionNodeType.Swizzle: + return new Vector2(Children[0].EvaluateSubchannel(Subchannels[0]), Children[0].EvaluateSubchannel(Subchannels[1])); + default: + throw new NotImplementedException(); + } + } + } +#pragma warning restore CS0660, CS0661 +} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Vector3Node.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Vector3Node.cs new file mode 100644 index 000000000..90ee6b07b --- /dev/null +++ b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Vector3Node.cs @@ -0,0 +1,404 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Numerics; +using Windows.UI.Composition; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork +{ + // Ignore warning: 'Vector3Node' defines operator == or operator != but does not override Object.Equals(object o) && Object.GetHashCode() +#pragma warning disable CS0660, CS0661 + /// + /// Class Vector3Node. This class cannot be inherited. + /// + /// + public sealed class Vector3Node : ExpressionNode + { + /// + /// Initializes a new instance of the class. + /// + internal Vector3Node() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The value. + internal Vector3Node(Vector3 value) + { + _value = value; + NodeType = ExpressionNodeType.ConstantValue; + } + + /// + /// Initializes a new instance of the class. + /// + /// Name of the parameter. + internal Vector3Node(string paramName) + { + ParamName = paramName; + NodeType = ExpressionNodeType.ConstantParameter; + } + + /// + /// Initializes a new instance of the class. + /// + /// Name of the parameter. + /// The value. + internal Vector3Node(string paramName, Vector3 value) + { + ParamName = paramName; + _value = value; + NodeType = ExpressionNodeType.ConstantParameter; + + SetVector3Parameter(paramName, value); + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value. + /// The result of the conversion. + public static implicit operator Vector3Node(Vector3 value) + { + return new Vector3Node(value); + } + + /// + /// Implements the + operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static Vector3Node operator +(Vector3Node left, Vector3Node right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Add, left, right); + } + + /// + /// Implements the - operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static Vector3Node operator -(Vector3Node left, Vector3Node right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Subtract, left, right); + } + + /// + /// Implements the - operator. + /// + /// The value. + /// The result of the operator. + public static Vector3Node operator -(Vector3Node value) + { + return ExpressionFunctions.Function(ExpressionNodeType.Negate, value); + } + + /// + /// Implements the * operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static Vector3Node operator *(Vector3Node left, ScalarNode right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); + } + + /// + /// Implements the * operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static Vector3Node operator *(Vector3Node left, Vector3Node right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); + } + + /// + /// Implements the / operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static Vector3Node operator /(Vector3Node left, Vector3Node right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Divide, left, right); + } + + /// + /// Implements the % operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static Vector3Node operator %(Vector3Node left, Vector3Node right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Modulus, left, right); + } + + /// + /// Implements the == operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static BooleanNode operator ==(Vector3Node left, Vector3Node right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Equals, left, right); + } + + /// + /// Implements the != operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static BooleanNode operator !=(Vector3Node left, Vector3Node right) + { + return ExpressionFunctions.Function(ExpressionNodeType.NotEquals, left, right); + } + + /// + /// Enum Subchannel + /// + public enum Subchannel + { + /// + /// The x channel + /// + X, + + /// + /// The y channel + /// + Y, + + /// + /// The z channel + /// + Z + } + + /// + /// Gets the x channel. + /// + /// The x. + public ScalarNode X + { + get { return GetSubchannels(Subchannel.X); } + } + + /// + /// Gets the y channel. + /// + /// The y. + public ScalarNode Y + { + get { return GetSubchannels(Subchannel.Y); } + } + + /// + /// Gets the z channel. + /// + /// The z. + public ScalarNode Z + { + get { return GetSubchannels(Subchannel.Z); } + } + + /// + /// Gets the x and y channel. + /// + /// The xy. + public Vector2Node XY + { + get { return GetSubchannels(Subchannel.X, Subchannel.Y); } + } + + /// + /// Create a new type by re-arranging the Vector subchannels. + /// + /// The subchannel. + /// ScalarNode + public ScalarNode GetSubchannels(Subchannel s) + { + return SubchannelsInternal(s.ToString()); + } + + /// + /// Create a new type by re-arranging the Vector subchannels. + /// + /// The first subchannel. + /// The second subchannel. + /// Vector2Node + public Vector2Node GetSubchannels(Subchannel s1, Subchannel s2) + { + return SubchannelsInternal(s1.ToString(), s2.ToString()); + } + + /// + /// Create a new type by re-arranging the Vector subchannels. + /// + /// The first subchannel. + /// The second subchannel. + /// The third subchannel. + /// Vector3Node + public Vector3Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3) + { + return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString()); + } + + /// + /// Create a new type by re-arranging the Vector subchannels. + /// + /// The first subchannel. + /// The second subchannel. + /// The third subchannel. + /// The fourth subchannel. + /// Vector4Node + public Vector4Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4) + { + return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString()); + } + + /// + /// Create a new type by re-arranging the Vector subchannels. + /// + /// The first subchannel. + /// The second subchannel. + /// The third subchannel. + /// The fourth subchannel. + /// The fifth subchannel. + /// The sixth subchannel. + /// Matrix3x2Node + public Matrix3x2Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4, Subchannel s5, Subchannel s6) + { + return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString(), s5.ToString(), s6.ToString()); + } + + /// + /// Create a new type by re-arranging the Vector subchannels. + /// + /// The first subchannel. + /// The second subchannel. + /// The third subchannel. + /// The fourth subchannel. + /// The fifth subchannel. + /// The sixth subchannel. + /// The seventh subchannel. + /// The eighth subchannel. + /// The ninth subchannel. + /// The tenth subchannel. + /// The eleventh subchannel. + /// The twelfth subchannel. + /// The thirteenth subchannel. + /// The fourteenth subchannel. + /// The fifteenth subchannel. + /// The sixteenth subchannel. + /// Matrix4x4Node +#pragma warning disable SA1117 // Parameters must be on same line or separate lines + public Matrix4x4Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4, + Subchannel s5, Subchannel s6, Subchannel s7, Subchannel s8, + Subchannel s9, Subchannel s10, Subchannel s11, Subchannel s12, + Subchannel s13, Subchannel s14, Subchannel s15, Subchannel s16) + { + return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString(), + s5.ToString(), s6.ToString(), s7.ToString(), s8.ToString(), + s9.ToString(), s10.ToString(), s11.ToString(), s12.ToString(), + s13.ToString(), s14.ToString(), s15.ToString(), s16.ToString()); + } +#pragma warning restore SA1117 // Parameters must be on same line or separate lines + + /// + /// Gets the value. + /// + /// System.String. + protected internal override string GetValue() + { + return $"Vector3({_value.X.ToCompositionString()},{_value.Y.ToCompositionString()},{_value.Z.ToCompositionString()})"; + } + + private Vector3 _value; + + /// + /// Evaluates the current value of the expression + /// + /// The current value of the expression + public Vector3 Evaluate() + { + switch (NodeType) + { + case ExpressionNodeType.ConstantValue: + return _value; + case ExpressionNodeType.ReferenceProperty: + var reference = (Children[0] as ReferenceNode).Reference; + return PropertyName switch + { + nameof(Visual.Offset) => (reference as Visual).Offset, + nameof(Visual.RotationAxis) => (reference as Visual).RotationAxis, + nameof(Visual.CenterPoint) => (reference as Visual).CenterPoint, + _ => GetProperty() + }; + + Vector3 GetProperty() + { + reference.Properties.TryGetVector3(PropertyName, out var value); + return value; + } + + case ExpressionNodeType.Conditional: + return + (Children[0] as BooleanNode).Evaluate() ? + (Children[1] as Vector3Node).Evaluate() : + (Children[2] as Vector3Node).Evaluate(); + case ExpressionNodeType.Add: + return + (Children[0] as Vector3Node).Evaluate() + + (Children[1] as Vector3Node).Evaluate(); + case ExpressionNodeType.Subtract: + return + (Children[0] as Vector3Node).Evaluate() - + (Children[1] as Vector3Node).Evaluate(); + case ExpressionNodeType.Lerp: + { + var t = (Children[2] as ScalarNode).Evaluate(); + return + (Children[0] as Vector3Node).Evaluate() * t - + (Children[1] as Vector3Node).Evaluate() * (1 - t); + } + case ExpressionNodeType.Negate: + return + -(Children[0] as Vector3Node).Evaluate(); + case ExpressionNodeType.Multiply: + return (Children[0], Children[1]) switch + { + (Vector3Node v1, Vector3Node v2) => v1.Evaluate() * v2.Evaluate(), + (Vector3Node v1, ScalarNode s2) => v1.Evaluate() * s2.Evaluate(), + (ScalarNode s1, Vector3Node v2) => s1.Evaluate() * v2.Evaluate(), + _ => throw new NotImplementedException() + }; + case ExpressionNodeType.Divide: + return + (Children[0] as Vector3Node).Evaluate() / + (Children[1] as Vector3Node).Evaluate(); + case ExpressionNodeType.Vector3: + return new Vector3( + (Children[0] as ScalarNode).Evaluate(), + (Children[1] as ScalarNode).Evaluate(), + (Children[2] as ScalarNode).Evaluate()); + case ExpressionNodeType.Swizzle: + return new Vector3(Children[0].EvaluateSubchannel(Subchannels[0]), Children[0].EvaluateSubchannel(Subchannels[1]), Children[0].EvaluateSubchannel(Subchannels[2])); + default: + throw new NotImplementedException(); + } + } + } +#pragma warning restore CS0660, CS0661 +} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Vector4Node.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Vector4Node.cs new file mode 100644 index 000000000..0d0e7bca3 --- /dev/null +++ b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Vector4Node.cs @@ -0,0 +1,418 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Numerics; +using Windows.UI.Composition; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork +{ + // Ignore warning: 'Vector4Node' defines operator == or operator != but does not override Object.Equals(object o) && Object.GetHashCode() +#pragma warning disable CS0660, CS0661 + /// + /// Class Vector4Node. This class cannot be inherited. + /// + /// + public sealed class Vector4Node : ExpressionNode + { + /// + /// Initializes a new instance of the class. + /// + internal Vector4Node() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The value. + internal Vector4Node(Vector4 value) + { + _value = value; + NodeType = ExpressionNodeType.ConstantValue; + } + + /// + /// Initializes a new instance of the class. + /// + /// Name of the parameter. + internal Vector4Node(string paramName) + { + ParamName = paramName; + NodeType = ExpressionNodeType.ConstantParameter; + } + + /// + /// Initializes a new instance of the class. + /// + /// Name of the parameter. + /// The value. + internal Vector4Node(string paramName, Vector4 value) + { + ParamName = paramName; + _value = value; + NodeType = ExpressionNodeType.ConstantParameter; + + SetVector4Parameter(paramName, value); + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value. + /// The result of the conversion. + public static implicit operator Vector4Node(Vector4 value) + { + return new Vector4Node(value); + } + + /// + /// Implements the + operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static Vector4Node operator +(Vector4Node left, Vector4Node right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Add, left, right); + } + + /// + /// Implements the - operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static Vector4Node operator -(Vector4Node left, Vector4Node right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Subtract, left, right); + } + + /// + /// Implements the - operator. + /// + /// The value. + /// The result of the operator. + public static Vector4Node operator -(Vector4Node value) + { + return ExpressionFunctions.Function(ExpressionNodeType.Negate, value); + } + + /// + /// Implements the * operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static Vector4Node operator *(Vector4Node left, ScalarNode right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); + } + + /// + /// Implements the * operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static Vector4Node operator *(Vector4Node left, Vector4Node right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); + } + + /// + /// Implements the / operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static Vector4Node operator /(Vector4Node left, Vector4Node right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Divide, left, right); + } + + /// + /// Implements the % operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static Vector4Node operator %(Vector4Node left, Vector4Node right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Modulus, left, right); + } + + /// + /// Implements the == operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static BooleanNode operator ==(Vector4Node left, Vector4Node right) + { + return ExpressionFunctions.Function(ExpressionNodeType.Equals, left, right); + } + + /// + /// Implements the != operator. + /// + /// The left. + /// The right. + /// The result of the operator. + public static BooleanNode operator !=(Vector4Node left, Vector4Node right) + { + return ExpressionFunctions.Function(ExpressionNodeType.NotEquals, left, right); + } + + /// + /// Enum Subchannel + /// + public enum Subchannel + { + /// + /// The x channel + /// + X, + + /// + /// The y channel + /// + Y, + + /// + /// The z channel + /// + Z, + + /// + /// The w channel + /// + W + } + + /// + /// Gets the x channel. + /// + /// The x. + public ScalarNode X + { + get { return GetSubchannels(Subchannel.X); } + } + + /// + /// Gets the y channel. + /// + /// The y. + public ScalarNode Y + { + get { return GetSubchannels(Subchannel.Y); } + } + + /// + /// Gets the z channel. + /// + /// The z. + public ScalarNode Z + { + get { return GetSubchannels(Subchannel.Z); } + } + + /// + /// Gets the w channel. + /// + /// The w. + public ScalarNode W + { + get { return GetSubchannels(Subchannel.W); } + } + + /// + /// Gets the x and y channels. + /// + /// The xy. + public Vector2Node XY + { + get { return GetSubchannels(Subchannel.X, Subchannel.Y); } + } + + /// + /// Gets the x, y, and z channels. + /// + /// The xyz. + public Vector3Node XYZ + { + get { return GetSubchannels(Subchannel.X, Subchannel.Y, Subchannel.Z); } + } + + /// + /// Create a new type by re-arranging the Vector subchannels. + /// + /// The subchannel. + /// ScalarNode + public ScalarNode GetSubchannels(Subchannel s) + { + return SubchannelsInternal(s.ToString()); + } + + /// + /// Create a new type by re-arranging the Vector subchannels. + /// + /// The first subchannel. + /// The second subchannel. + /// Vector2Node + public Vector2Node GetSubchannels(Subchannel s1, Subchannel s2) + { + return SubchannelsInternal(s1.ToString(), s2.ToString()); + } + + /// + /// Create a new type by re-arranging the Vector subchannels. + /// + /// The first subchannel. + /// The second subchannel. + /// The third subchannel. + /// Vector3Node + public Vector3Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3) + { + return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString()); + } + + /// + /// Create a new type by re-arranging the Vector subchannels. + /// + /// The first subchannel. + /// The second subchannel. + /// The third subchannel. + /// The fourth subchannel. + /// Vector4Node + public Vector4Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4) + { + return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString()); + } + + /// + /// Create a new type by re-arranging the Vector subchannels. + /// + /// The first subchannel. + /// The second subchannel. + /// The third subchannel. + /// The fourth subchannel. + /// The fifth subchannel. + /// The sixth subchannel. + /// Matrix3x2Node + public Matrix3x2Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4, Subchannel s5, Subchannel s6) + { + return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString(), s5.ToString(), s6.ToString()); + } + + /// + /// Create a new type by re-arranging the Vector subchannels. + /// + /// The first subchannel. + /// The second subchannel. + /// The third subchannel. + /// The fourth subchannel. + /// The fifth subchannel. + /// The sixth subchannel. + /// The seventh subchannel. + /// The eighth subchannel. + /// The ninth subchannel. + /// The tenth subchannel. + /// The eleventh subchannel. + /// The twelfth subchannel. + /// The thirteenth subchannel. + /// The fourteenth subchannel. + /// The fifteenth subchannel. + /// The sixteenth subchannel. + /// Matrix4x4Node +#pragma warning disable SA1117 // Parameters must be on same line or separate lines + public Matrix4x4Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4, + Subchannel s5, Subchannel s6, Subchannel s7, Subchannel s8, + Subchannel s9, Subchannel s10, Subchannel s11, Subchannel s12, + Subchannel s13, Subchannel s14, Subchannel s15, Subchannel s16) + { + return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString(), + s5.ToString(), s6.ToString(), s7.ToString(), s8.ToString(), + s9.ToString(), s10.ToString(), s11.ToString(), s12.ToString(), + s13.ToString(), s14.ToString(), s15.ToString(), s16.ToString()); + } +#pragma warning restore SA1117 // Parameters must be on same line or separate lines + + /// + /// Gets the value. + /// + /// System.String. + protected internal override string GetValue() + { + return $"Vector4({_value.X.ToCompositionString()},{_value.Y.ToCompositionString()},{_value.Z.ToCompositionString()},{_value.W.ToCompositionString()})"; + } + + private Vector4 _value; + + /// + /// Evaluates the current value of the expression + /// + /// The current value of the expression + public Vector4 Evaluate() + { + switch (NodeType) + { + case ExpressionNodeType.ConstantParameter: + throw new NotImplementedException(); + case ExpressionNodeType.ReferenceProperty: + var reference = (Children[0] as ReferenceNode).Reference; + return PropertyName switch + { + _ => GetProperty() + }; + + Vector4 GetProperty() + { + reference.Properties.TryGetVector4(PropertyName, out var value); + return value; + } + + case ExpressionNodeType.Conditional: + return + (Children[0] as BooleanNode).Evaluate() ? + (Children[1] as Vector4Node).Evaluate() : + (Children[2] as Vector4Node).Evaluate(); + case ExpressionNodeType.Add: + return + (Children[0] as Vector4Node).Evaluate() + + (Children[1] as Vector4Node).Evaluate(); + case ExpressionNodeType.Subtract: + return + (Children[0] as Vector4Node).Evaluate() - + (Children[1] as Vector4Node).Evaluate(); + case ExpressionNodeType.Negate: + return + -(Children[0] as Vector4Node).Evaluate(); + case ExpressionNodeType.Multiply: + return (Children[0], Children[1]) switch + { + (Vector4Node v1, Vector4Node v2) => v1.Evaluate() * v2.Evaluate(), + (Vector4Node v1, ScalarNode s2) => v1.Evaluate() * s2.Evaluate(), + (ScalarNode s1, Vector4Node v2) => s1.Evaluate() * v2.Evaluate(), + _ => throw new NotImplementedException() + }; + case ExpressionNodeType.Divide: + return + (Children[0] as Vector4Node).Evaluate() / + (Children[1] as Vector4Node).Evaluate(); + case ExpressionNodeType.Vector3: + return new Vector4( + (Children[0] as ScalarNode).Evaluate(), + (Children[1] as ScalarNode).Evaluate(), + (Children[2] as ScalarNode).Evaluate(), + (Children[2] as ScalarNode).Evaluate()); + case ExpressionNodeType.Swizzle: + return new Vector4(Children[0].EvaluateSubchannel(Subchannels[0]), Children[0].EvaluateSubchannel(Subchannels[1]), Children[0].EvaluateSubchannel(Subchannels[2]), Children[0].EvaluateSubchannel(Subchannels[3])); + default: + throw new NotImplementedException(); + } + } + } +#pragma warning restore CS0660, CS0661 +} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionValues/ExpressionValues.Constant.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionValues/ExpressionValues.Constant.cs new file mode 100644 index 000000000..e56d2cfcc --- /dev/null +++ b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionValues/ExpressionValues.Constant.cs @@ -0,0 +1,216 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Numerics; +using Windows.UI; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork +{ + // ExpressionValues is a static class instead of a namespace to improve intellisense discoverablity and consistency with the other helper classes. + + /// + /// Class ExpressionValues. + /// + public static partial class ExpressionValues + { + /// + /// Create a constant parameter whose value can be changed without recreating the expression. + /// + public static class Constant + { + // Constant parameters with no default value + + /// + /// Creates a named constant parameter of type bool. + /// + /// The name that will be used to refer to the parameter at a later time. + /// BooleanNode + public static BooleanNode CreateConstantBoolean(string paramName) + { + return new BooleanNode(paramName); + } + + /// + /// Creates a named constant parameter of type float. + /// + /// The name that will be used to refer to the parameter at a later time. + /// ScalarNode. + public static ScalarNode CreateConstantScalar(string paramName) + { + return new ScalarNode(paramName); + } + + /// + /// Creates a named constant parameter of type Vector2. + /// + /// The name that will be used to refer to the parameter at a later time. + /// Vector2Node. + public static Vector2Node CreateConstantVector2(string paramName) + { + return new Vector2Node(paramName); + } + + /// + /// Creates a named constant parameter of type Vector3. + /// + /// The name that will be used to refer to the parameter at a later time. + /// Vector3Node. + public static Vector3Node CreateConstantVector3(string paramName) + { + return new Vector3Node(paramName); + } + + /// + /// Creates a named constant parameter of type Vector4. + /// + /// The name that will be used to refer to the parameter at a later time. + /// Vector4Node. + public static Vector4Node CreateConstantVector4(string paramName) + { + return new Vector4Node(paramName); + } + + /// + /// Creates a named constant parameter of type Color. + /// + /// The name that will be used to refer to the parameter at a later time. + /// ColorNode. + public static ColorNode CreateConstantColor(string paramName) + { + return new ColorNode(paramName); + } + + /// + /// Creates a named constant parameter of type Quaternion. + /// + /// The name that will be used to refer to the parameter at a later time. + /// QuaternionNode. + public static QuaternionNode CreateConstantQuaternion(string paramName) + { + return new QuaternionNode(paramName); + } + + /// + /// Creates a named constant parameter of type Matrix3x2. + /// + /// The name that will be used to refer to the parameter at a later time. + /// Matrix3x2Node. + public static Matrix3x2Node CreateConstantMatrix3x2(string paramName) + { + return new Matrix3x2Node(paramName); + } + + /// + /// Creates a named constant parameter of type Matrix4x4. + /// + /// The name that will be used to refer to the parameter at a later time. + /// Matrix4x4Node. + public static Matrix4x4Node CreateConstantMatrix4x4(string paramName) + { + return new Matrix4x4Node(paramName); + } + + // Constant parameters with a default value + + /// + /// Creates a named constant parameter of type bool, initialized with the specified value. + /// + /// The name that will be used to refer to the parameter at a later time. + /// The value of the parameter. + /// BooleanNode. + public static BooleanNode CreateConstantBoolean(string paramName, bool value) + { + return new BooleanNode(paramName, value); + } + + /// + /// Creates a named constant parameter of type float, initialized with the specified value. + /// + /// The name that will be used to refer to the parameter at a later time. + /// The value of the parameter. + /// ScalarNode. + public static ScalarNode CreateConstantScalar(string paramName, float value) + { + return new ScalarNode(paramName, value); + } + + /// + /// Creates a named constant parameter of type Vector2, initialized with the specified value. + /// + /// The name that will be used to refer to the parameter at a later time. + /// The value of the parameter. + /// Vector2Node. + public static Vector2Node CreateConstantVector2(string paramName, Vector2 value) + { + return new Vector2Node(paramName, value); + } + + /// + /// Creates a named constant parameter of type Vector3, initialized with the specified value. + /// + /// The name that will be used to refer to the parameter at a later time. + /// The value of the parameter. + /// Vector3Node. + public static Vector3Node CreateConstantVector3(string paramName, Vector3 value) + { + return new Vector3Node(paramName, value); + } + + /// + /// Creates a named constant parameter of type Vector4, initialized with the specified value. + /// + /// The name that will be used to refer to the parameter at a later time. + /// The value of the parameter. + /// Vector4Node. + public static Vector4Node CreateConstantVector4(string paramName, Vector4 value) + { + return new Vector4Node(paramName, value); + } + + /// + /// Creates a named constant parameter of type Color, initialized with the specified value. + /// + /// The name that will be used to refer to the parameter at a later time. + /// The value of the parameter. + /// ColorNode. + public static ColorNode CreateConstantColor(string paramName, Color value) + { + return new ColorNode(paramName, value); + } + + /// + /// Creates a named constant parameter of type Quaternion, initialized with the specified value. + /// + /// The name that will be used to refer to the parameter at a later time. + /// The value of the parameter. + /// QuaternionNode. + public static QuaternionNode CreateConstantQuaternion(string paramName, Quaternion value) + { + return new QuaternionNode(paramName, value); + } + + /// + /// Creates a named constant parameter of type Matrix3x2, initialized with the specified value. + /// + /// The name that will be used to refer to the parameter at a later time. + /// The value of the parameter. + /// Matrix3x2Node. + public static Matrix3x2Node CreateConstantMatrix3x2(string paramName, Matrix3x2 value) + { + return new Matrix3x2Node(paramName, value); + } + + /// + /// Creates a named constant parameter of type Matrix4x4, initialized with the specified value. + /// + /// The name that will be used to refer to the parameter at a later time. + /// The value of the parameter. + /// Matrix4x4Node. + public static Matrix4x4Node CreateConstantMatrix4x4(string paramName, Matrix4x4 value) + { + return new Matrix4x4Node(paramName, value); + } + } + } +} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionValues/ExpressionValues.CurrentValue.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionValues/ExpressionValues.CurrentValue.cs new file mode 100644 index 000000000..e6a5ce346 --- /dev/null +++ b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionValues/ExpressionValues.CurrentValue.cs @@ -0,0 +1,101 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork +{ + // ExpressionValues is a static class instead of a namespace to improve intellisense discoverablity and consistency with the other helper classes. + + /// + /// Class ExpressionValues. + /// + public static partial class ExpressionValues + { + /// + /// Refer to the current value of the property this expression is connected to. + /// + public static class CurrentValue + { + /// + /// Create a reference to the current value of the boolean property that this expression will be connected to. + /// + /// BooleanNode. + public static BooleanNode CreateBooleanCurrentValue() + { + return ExpressionNode.CreateValueKeyword(ValueKeywordKind.CurrentValue); + } + + /// + /// Create a reference to the current value of the float property that this expression will be connected to. + /// + /// ScalarNode. + public static ScalarNode CreateScalarCurrentValue() + { + return ExpressionNode.CreateValueKeyword(ValueKeywordKind.CurrentValue); + } + + /// + /// Create a reference to the current value of the Vector2 property that this expression will be connected to. + /// + /// Vector2Node. + public static Vector2Node CreateVector2CurrentValue() + { + return ExpressionNode.CreateValueKeyword(ValueKeywordKind.CurrentValue); + } + + /// + /// Create a reference to the current value of the Vector3 property that this expression will be connected to. + /// + /// Vector3Node. + public static Vector3Node CreateVector3CurrentValue() + { + return ExpressionNode.CreateValueKeyword(ValueKeywordKind.CurrentValue); + } + + /// + /// Create a reference to the current value of the Vector4 property that this expression will be connected to. + /// + /// Vector4Node. + public static Vector4Node CreateVector4CurrentValue() + { + return ExpressionNode.CreateValueKeyword(ValueKeywordKind.CurrentValue); + } + + /// + /// Create a reference to the current value of the Color property that this expression will be connected to. + /// + /// ColorNode. + public static ColorNode CreateColorCurrentValue() + { + return ExpressionNode.CreateValueKeyword(ValueKeywordKind.CurrentValue); + } + + /// + /// Create a reference to the current value of the Quaternion property that this expression will be connected to. + /// + /// QuaternionNode. + public static QuaternionNode CreateQuaternionCurrentValue() + { + return ExpressionNode.CreateValueKeyword(ValueKeywordKind.CurrentValue); + } + + /// + /// Create a reference to the current value of the Matrix3x2 property that this expression will be connected to. + /// + /// Matrix3x2Node. + public static Matrix3x2Node CreateMatrix3x2CurrentValue() + { + return ExpressionNode.CreateValueKeyword(ValueKeywordKind.CurrentValue); + } + + /// + /// Create a reference to the current value of the Matrix4x4 property that this expression will be connected to. + /// + /// Matrix4x4Node. + public static Matrix4x4Node CreateMatrix4x4CurrentValue() + { + return ExpressionNode.CreateValueKeyword(ValueKeywordKind.CurrentValue); + } + } + } +} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionValues/ExpressionValues.Reference.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionValues/ExpressionValues.Reference.cs new file mode 100644 index 000000000..018d77dee --- /dev/null +++ b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionValues/ExpressionValues.Reference.cs @@ -0,0 +1,140 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork +{ + // ExpressionValues is a static class instead of a namespace to improve intellisense discoverablity and consistency with the other helper classes. + + /// + /// Class ExpressionValues. + /// + public static partial class ExpressionValues + { + /// + /// Create a reference to a CompositionObject. + /// + public static class Reference + { + /// + /// Creates a named reference parameter to an AmbientLight. + /// + /// The name that will be used to refer to the parameter at a later time. + /// AmbientLightReferenceNode. + public static AmbientLightReferenceNode CreateAmbientLightReference(string parameterName) + { + return new AmbientLightReferenceNode(parameterName); + } + + /// + /// Creates a named reference parameter to a ColorBrush. + /// + /// The name that will be used to refer to the parameter at a later time. + /// ColorBrushReferenceNode. + public static ColorBrushReferenceNode CreateColorBrushReference(string parameterName) + { + return new ColorBrushReferenceNode(parameterName); + } + + /// + /// Creates a named reference parameter to a DistantLight. + /// + /// The name that will be used to refer to the parameter at a later time. + /// DistantLightReferenceNode. + public static DistantLightReferenceNode CreateDistantLightReference(string parameterName) + { + return new DistantLightReferenceNode(parameterName); + } + + /// + /// Creates a named reference parameter to a DropShadow. + /// + /// The name that will be used to refer to the parameter at a later time. + /// DropShadowReferenceNode. + public static DropShadowReferenceNode CreateDropShadowReference(string parameterName) + { + return new DropShadowReferenceNode(parameterName); + } + + /// + /// Creates a named reference parameter to an InsetClip. + /// + /// The name that will be used to refer to the parameter at a later time. + /// InsetClipReferenceNode. + public static InsetClipReferenceNode CreateInsetClipReference(string parameterName) + { + return new InsetClipReferenceNode(parameterName); + } + + /// + /// Creates a named reference parameter to an InteractionTracker. + /// + /// The name that will be used to refer to the parameter at a later time. + /// InteractionTrackerReferenceNode. + public static InteractionTrackerReferenceNode CreateInteractionTrackerReference(string parameterName) + { + return new InteractionTrackerReferenceNode(parameterName); + } + + /// + /// Creates a named reference parameter to a NineGridBrush. + /// + /// The name that will be used to refer to the parameter at a later time. + /// NineGridBrushReferenceNode. + public static NineGridBrushReferenceNode CreateNineGridBrushReference(string parameterName) + { + return new NineGridBrushReferenceNode(parameterName); + } + + /// + /// Creates a named reference parameter to a PointLight. + /// + /// The name that will be used to refer to the parameter at a later time. + /// PointLightReferenceNode. + public static PointLightReferenceNode CreatePointLightReference(string parameterName) + { + return new PointLightReferenceNode(parameterName); + } + + /// + /// Creates a named reference parameter to a PropertySet. + /// + /// The name that will be used to refer to the parameter at a later time. + /// PropertySetReferenceNode. + public static PropertySetReferenceNode CreatePropertySetReference(string parameterName) + { + return new PropertySetReferenceNode(parameterName); + } + + /// + /// Creates a named reference parameter to a SpotLight. + /// + /// The name that will be used to refer to the parameter at a later time. + /// SpotLightReferenceNode. + public static SpotLightReferenceNode CreateSpotLightReference(string parameterName) + { + return new SpotLightReferenceNode(parameterName); + } + + /// + /// Creates a named reference parameter to a SurfaceBrush. + /// + /// The name that will be used to refer to the parameter at a later time. + /// SurfaceBrushReferenceNode. + public static SurfaceBrushReferenceNode CreateSurfaceBrushReference(string parameterName) + { + return new SurfaceBrushReferenceNode(parameterName); + } + + /// + /// Creates a named reference parameter to a Visual. + /// + /// The name that will be used to refer to the parameter at a later time. + /// VisualReferenceNode. + public static VisualReferenceNode CreateVisualReference(string parameterName) + { + return new VisualReferenceNode(parameterName); + } + } + } +} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionValues/ExpressionValues.StartingValue.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionValues/ExpressionValues.StartingValue.cs new file mode 100644 index 000000000..99d932e5c --- /dev/null +++ b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionValues/ExpressionValues.StartingValue.cs @@ -0,0 +1,101 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork +{ + // ExpressionValues is a static class instead of a namespace to improve intellisense discoverablity and consistency with the other helper classes. + + /// + /// Class ExpressionValues. + /// + public static partial class ExpressionValues + { + /// + /// Refer to the value of the property this expression is connected to, sampled during the first frame of execution. + /// + public static class StartingValue + { + /// + /// Create a reference to the starting value of the boolean property that this expression will be connected to. + /// + /// BooleanNode. + public static BooleanNode CreateBooleanStartingValue() + { + return ExpressionNode.CreateValueKeyword(ValueKeywordKind.StartingValue); + } + + /// + /// Create a reference to the starting value of the float property that this expression will be connected to. + /// + /// ScalarNode. + public static ScalarNode CreateScalarStartingValue() + { + return ExpressionNode.CreateValueKeyword(ValueKeywordKind.StartingValue); + } + + /// + /// Create a reference to the starting value of the Vector2 property that this expression will be connected to. + /// + /// Vector2Node. + public static Vector2Node CreateVector2StartingValue() + { + return ExpressionNode.CreateValueKeyword(ValueKeywordKind.StartingValue); + } + + /// + /// Create a reference to the starting value of the Vector3 property that this expression will be connected to. + /// + /// Vector3Node. + public static Vector3Node CreateVector3StartingValue() + { + return ExpressionNode.CreateValueKeyword(ValueKeywordKind.StartingValue); + } + + /// + /// Create a reference to the starting value of the Vector4 property that this expression will be connected to. + /// + /// Vector4Node. + public static Vector4Node CreateVector4StartingValue() + { + return ExpressionNode.CreateValueKeyword(ValueKeywordKind.StartingValue); + } + + /// + /// Create a reference to the starting value of the Color property that this expression will be connected to. + /// + /// ColorNode. + public static ColorNode CreateColorStartingValue() + { + return ExpressionNode.CreateValueKeyword(ValueKeywordKind.StartingValue); + } + + /// + /// Create a reference to the starting value of the Quaternion property that this expression will be connected to. + /// + /// QuaternionNode. + public static QuaternionNode CreateQuaternionStartingValue() + { + return ExpressionNode.CreateValueKeyword(ValueKeywordKind.StartingValue); + } + + /// + /// Create a reference to the starting value of the Matrix3x2 property that this expression will be connected to. + /// + /// Matrix3x2Node. + public static Matrix3x2Node CreateMatrix3x2StartingValue() + { + return ExpressionNode.CreateValueKeyword(ValueKeywordKind.StartingValue); + } + + /// + /// Create a reference to the starting value of the Matrix4x4 property that this expression will be connected to. + /// + /// Matrix4x4Node. + public static Matrix4x4Node CreateMatrix4x4StartingValue() + { + return ExpressionNode.CreateValueKeyword(ValueKeywordKind.StartingValue); + } + } + } +} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionValues/ExpressionValues.Target.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionValues/ExpressionValues.Target.cs new file mode 100644 index 000000000..b51d7f754 --- /dev/null +++ b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionValues/ExpressionValues.Target.cs @@ -0,0 +1,128 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork +{ + // ExpressionValues is a static class instead of a namespace to improve intellisense discoverablity and consistency with the other helper classes. + + /// + /// Class ExpressionValues. + /// + public static partial class ExpressionValues + { + /// + /// Create a reference to the CompositionObject this expression will be connected to. + /// + public static class Target + { + /// + /// Create a reference to the AmbientLight target that this expression will be connected to. + /// + /// AmbientLightReferenceNode. + public static AmbientLightReferenceNode CreateAmbientLightTarget() + { + return AmbientLightReferenceNode.CreateTargetReference(); + } + + /// + /// Create a reference to the ColorBrush target that this expression will be connected to. + /// + /// ColorBrushReferenceNode. + public static ColorBrushReferenceNode CreateColorBrushTarget() + { + return ColorBrushReferenceNode.CreateTargetReference(); + } + + /// + /// Create a reference to the DistantLight target that this expression will be connected to. + /// + /// DistantLightReferenceNode. + public static DistantLightReferenceNode CreateDistantLightTarget() + { + return DistantLightReferenceNode.CreateTargetReference(); + } + + /// + /// Create a reference to the DropShadow target that this expression will be connected to. + /// + /// DropShadowReferenceNode. + public static DropShadowReferenceNode CreateDropShadowTarget() + { + return DropShadowReferenceNode.CreateTargetReference(); + } + + /// + /// Create a reference to the InsetClip target that this expression will be connected to. + /// + /// InsetClipReferenceNode. + public static InsetClipReferenceNode CreateInsetClipTarget() + { + return InsetClipReferenceNode.CreateTargetReference(); + } + + /// + /// Create a reference to the InteractionTracker target that this expression will be connected to. + /// + /// InteractionTrackerReferenceNode. + public static InteractionTrackerReferenceNode CreateInteractionTrackerTarget() + { + return InteractionTrackerReferenceNode.CreateTargetReference(); + } + + /// + /// Create a reference to the NineGridBrush target that this expression will be connected to. + /// + /// NineGridBrushReferenceNode. + public static NineGridBrushReferenceNode CreateNineGridBrushTarget() + { + return NineGridBrushReferenceNode.CreateTargetReference(); + } + + /// + /// Create a reference to the PointLight target that this expression will be connected to. + /// + /// PointLightReferenceNode. + public static PointLightReferenceNode CreatePointLightTarget() + { + return PointLightReferenceNode.CreateTargetReference(); + } + + /// + /// Create a reference to the PropertySet target that this expression will be connected to. + /// + /// PropertySetReferenceNode. + public static PropertySetReferenceNode CreatePropertySetTarget() + { + return PropertySetReferenceNode.CreateTargetReference(); + } + + /// + /// Create a reference to the SpotLight target that this expression will be connected to. + /// + /// SpotLightReferenceNode. + public static SpotLightReferenceNode CreateSpotLightTarget() + { + return SpotLightReferenceNode.CreateTargetReference(); + } + + /// + /// Create a reference to the SurfaceBrush target that this expression will be connected to. + /// + /// SurfaceBrushReferenceNode. + public static SurfaceBrushReferenceNode CreateSurfaceBrushTarget() + { + return SurfaceBrushReferenceNode.CreateTargetReference(); + } + + /// + /// Create a reference to the Visual target that this expression will be connected to. + /// + /// VisualReferenceNode. + public static VisualReferenceNode CreateVisualTarget() + { + return VisualReferenceNode.CreateTargetReference(); + } + } + } +} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/FloatExtensions.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/FloatExtensions.cs new file mode 100644 index 000000000..2f22295af --- /dev/null +++ b/labs/CompositionCollectionView/ExpressionsFork/Expressions/FloatExtensions.cs @@ -0,0 +1,48 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics.Contracts; + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + /// An extension for the type + /// + internal static class FloatExtensions + { + /// + /// Returns a representation of a that avoids scientific notation, which is not compatible with the composition expression animations API + /// + /// The input to process + /// A representation of that can be used in a expression animation + [Pure] + public static string ToCompositionString(this float number) + { + var defaultString = number.ToString(System.Globalization.CultureInfo.InvariantCulture); + var eIndex = defaultString.IndexOf('E'); + + // If the default string representation is not in scientific notation, we can use it + if (eIndex == -1) + { + return defaultString; + } + + // If the number uses scientific notation because it is too large, we can print it without the decimal places + var exponent = int.Parse(defaultString.Substring(eIndex + 1)); + if (exponent >= 0) + { + return number.ToString($"F0", System.Globalization.CultureInfo.InvariantCulture); + } + + // Otherwise, we need to print it with the right number of decimals + var decimalPlaces = -exponent // The number of decimal places is the exponent of 10 + + eIndex // Plus each character in the mantissa + + (number < 0 ? + -3 : // Minus the sign, dot and first number of the mantissa if negative + -2); // Minus the dot and first number of the mantissa otherwise + + return number.ToString($"F{decimalPlaces}", System.Globalization.CultureInfo.InvariantCulture); + } + } +} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/OperationType.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/OperationType.cs new file mode 100644 index 000000000..6728b93dc --- /dev/null +++ b/labs/CompositionCollectionView/ExpressionsFork/Expressions/OperationType.cs @@ -0,0 +1,47 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork +{ + /// + /// Enum OperationType + /// + internal enum OperationType + { + /// + /// The function + /// + Function, + + /// + /// The operator (takes two operands) + /// + Operator, + + /// + /// The operator that only takes one operand + /// + UnaryOperator, + + /// + /// The constant + /// + Constant, + + /// + /// The reference + /// + Reference, + + /// + /// The conditional + /// + Conditional, + + /// + /// The swizzle + /// + Swizzle, + } +} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/AmbientLightReferenceNode.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/AmbientLightReferenceNode.cs new file mode 100644 index 000000000..edce187bd --- /dev/null +++ b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/AmbientLightReferenceNode.cs @@ -0,0 +1,46 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Windows.UI.Composition; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork +{ + /// + /// Class AmbientLightReferenceNode. This class cannot be inherited. + /// + /// + public sealed class AmbientLightReferenceNode : ReferenceNode + { + /// + /// Initializes a new instance of the class. + /// + /// Name of the parameter. + /// The light. + internal AmbientLightReferenceNode(string paramName, AmbientLight light = null) + : base(paramName, light) + { + } + + /// + /// Creates the target reference. + /// + /// AmbientLightReferenceNode. + internal static AmbientLightReferenceNode CreateTargetReference() + { + var node = new AmbientLightReferenceNode(null); + node.NodeType = ExpressionNodeType.TargetReference; + + return node; + } + + /// + /// Gets the color. + /// + /// The color. + public ColorNode Color + { + get { return ReferenceProperty("Color"); } + } + } +} diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/ColorBrushReferenceNode.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/ColorBrushReferenceNode.cs new file mode 100644 index 000000000..0a20a4e94 --- /dev/null +++ b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/ColorBrushReferenceNode.cs @@ -0,0 +1,46 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Windows.UI.Composition; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork +{ + /// + /// Class ColorBrushReferenceNode. This class cannot be inherited. + /// + /// + public sealed class ColorBrushReferenceNode : ReferenceNode + { + /// + /// Initializes a new instance of the class. + /// + /// Name of the parameter. + /// The brush. + internal ColorBrushReferenceNode(string paramName, CompositionColorBrush brush = null) + : base(paramName, brush) + { + } + + /// + /// Creates the target reference. + /// + /// ColorBrushReferenceNode. + internal static ColorBrushReferenceNode CreateTargetReference() + { + var node = new ColorBrushReferenceNode(null); + node.NodeType = ExpressionNodeType.TargetReference; + + return node; + } + + /// + /// Gets the color. + /// + /// The color. + public ColorNode Color + { + get { return ReferenceProperty("Color"); } + } + } +} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/DistantLightReferenceNode.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/DistantLightReferenceNode.cs new file mode 100644 index 000000000..2aa369217 --- /dev/null +++ b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/DistantLightReferenceNode.cs @@ -0,0 +1,55 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Windows.UI.Composition; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork +{ + /// + /// Class DistantLightReferenceNode. This class cannot be inherited. + /// + /// + public sealed class DistantLightReferenceNode : ReferenceNode + { + /// + /// Initializes a new instance of the class. + /// + /// Name of the parameter. + /// The light. + internal DistantLightReferenceNode(string paramName, DistantLight light = null) + : base(paramName, light) + { + } + + /// + /// Creates the target reference. + /// + /// DistantLightReferenceNode. + internal static DistantLightReferenceNode CreateTargetReference() + { + var node = new DistantLightReferenceNode(null); + node.NodeType = ExpressionNodeType.TargetReference; + + return node; + } + + /// + /// Gets the color. + /// + /// The color. + public ColorNode Color + { + get { return ReferenceProperty("Color"); } + } + + /// + /// Gets the direction. + /// + /// The direction. + public Vector3Node Direction + { + get { return ReferenceProperty("Direction"); } + } + } +} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/DropShadowReferenceNode.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/DropShadowReferenceNode.cs new file mode 100644 index 000000000..658642177 --- /dev/null +++ b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/DropShadowReferenceNode.cs @@ -0,0 +1,73 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Windows.UI.Composition; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork +{ + /// + /// Class DropShadowReferenceNode. This class cannot be inherited. + /// + /// + public sealed class DropShadowReferenceNode : ReferenceNode + { + /// + /// Initializes a new instance of the class. + /// + /// Name of the parameter. + /// The source. + internal DropShadowReferenceNode(string paramName, DropShadow source = null) + : base(paramName, source) + { + } + + /// + /// Creates the target reference. + /// + /// DropShadowReferenceNode. + internal static DropShadowReferenceNode CreateTargetReference() + { + var node = new DropShadowReferenceNode(null); + node.NodeType = ExpressionNodeType.TargetReference; + + return node; + } + + /// + /// Gets the blur radius. + /// + /// The blur radius. + public ScalarNode BlurRadius + { + get { return ReferenceProperty("BlurRadius"); } + } + + /// + /// Gets the opacity. + /// + /// The opacity. + public ScalarNode Opacity + { + get { return ReferenceProperty("Opacity"); } + } + + /// + /// Gets the offset. + /// + /// The offset. + public Vector3Node Offset + { + get { return ReferenceProperty("Offset"); } + } + + /// + /// Gets the color. + /// + /// The color. + public ColorNode Color + { + get { return ReferenceProperty("Color"); } + } + } +} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/InsetClipReferenceNode.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/InsetClipReferenceNode.cs new file mode 100644 index 000000000..f83f28944 --- /dev/null +++ b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/InsetClipReferenceNode.cs @@ -0,0 +1,136 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Windows.UI.Composition; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork +{ + /// + /// Class InsetClipReferenceNode. This class cannot be inherited. + /// + /// + public sealed class InsetClipReferenceNode : ReferenceNode + { + /// + /// Initializes a new instance of the class. + /// + /// Name of the parameter. + /// The ic. + internal InsetClipReferenceNode(string paramName, InsetClip ic = null) + : base(paramName, ic) + { + } + + /// + /// Creates the target reference. + /// + /// InsetClipReferenceNode. + internal static InsetClipReferenceNode CreateTargetReference() + { + var node = new InsetClipReferenceNode(null); + node.NodeType = ExpressionNodeType.TargetReference; + + return node; + } + + /// + /// Gets the bottom inset. + /// + /// The bottom inset. + public ScalarNode BottomInset + { + get { return ReferenceProperty("BottomInset"); } + } + + /// + /// Gets the left inset. + /// + /// The left inset. + public ScalarNode LeftInset + { + get { return ReferenceProperty("LeftInset"); } + } + + /// + /// Gets the right inset. + /// + /// The right inset. + public ScalarNode RightInset + { + get { return ReferenceProperty("RightInset"); } + } + + /// + /// Gets the top inset. + /// + /// The top inset. + public ScalarNode TopInset + { + get { return ReferenceProperty("TopInset"); } + } + + /// + /// Gets the rotation angle. + /// + /// The rotation angle. + public ScalarNode RotationAngle + { + get { return ReferenceProperty("RotationAngle"); } + } + + /// + /// Gets the rotation angle in degrees. + /// + /// The rotation angle in degrees. + public ScalarNode RotationAngleInDegrees + { + get { return ReferenceProperty("RotationAngleInDegrees"); } + } + + /// + /// Gets the anchor point. + /// + /// The anchor point. + public Vector2Node AnchorPoint + { + get { return ReferenceProperty("AnchorPoint"); } + } + + /// + /// Gets the center point. + /// + /// The center point. + public Vector2Node CenterPoint + { + get { return ReferenceProperty("CenterPoint"); } + } + + /// + /// Gets the offset. + /// + /// The offset. + public Vector2Node Offset + { + get { return ReferenceProperty("Offset"); } + } + + /// + /// Gets the scale. + /// + /// The scale. + public Vector2Node Scale + { + get { return ReferenceProperty("Scale"); } + } + + /// + /// Gets the transform matrix. + /// + /// The transform matrix. + public Matrix3x2Node TransformMatrix + { + get { return ReferenceProperty("TransformMatrix"); } + } + } +} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/InteractionTrackerReferenceNode.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/InteractionTrackerReferenceNode.cs new file mode 100644 index 000000000..e730515d1 --- /dev/null +++ b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/InteractionTrackerReferenceNode.cs @@ -0,0 +1,154 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Windows.UI.Composition.Interactions; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork +{ + /// + /// Class InteractionTrackerReferenceNode. This class cannot be inherited. + /// + /// + public sealed class InteractionTrackerReferenceNode : ReferenceNode + { + /// + /// Initializes a new instance of the class. + /// + /// Name of the parameter. + /// It. + internal InteractionTrackerReferenceNode(string paramName, InteractionTracker it = null) + : base(paramName, it) + { + } + + /// + /// Creates the target reference. + /// + /// InteractionTrackerReferenceNode. + internal static InteractionTrackerReferenceNode CreateTargetReference() + { + var node = new InteractionTrackerReferenceNode(null); + node.NodeType = ExpressionNodeType.TargetReference; + + return node; + } + + /// + /// Gets the is position rounding suggested. + /// + /// The is position rounding suggested. + public BooleanNode IsPositionRoundingSuggested + { + get { return ReferenceProperty("IsPositionRoundingSuggested"); } + } + + /// + /// Gets the minimum scale. + /// + /// The minimum scale. + public ScalarNode MinScale + { + get { return ReferenceProperty("MinScale"); } + } + + /// + /// Gets the maximum scale. + /// + /// The maximum scale. + public ScalarNode MaxScale + { + get { return ReferenceProperty("MaxScale"); } + } + + /// + /// Gets the natural resting scale. + /// + /// The natural resting scale. + public ScalarNode NaturalRestingScale + { + get { return ReferenceProperty("NaturalRestingScale"); } + } + + /// + /// Gets the scale. + /// + /// The scale. + public ScalarNode Scale + { + get { return ReferenceProperty("Scale"); } + } + + /// + /// Gets the scale inertia decay rate. + /// + /// The scale inertia decay rate. + public ScalarNode ScaleInertiaDecayRate + { + get { return ReferenceProperty("ScaleInertiaDecayRate"); } + } + + /// + /// Gets the scale velocity in percent per second. + /// + /// The scale velocity in percent per second. + public ScalarNode ScaleVelocityInPercentPerSecond + { + get { return ReferenceProperty("ScaleVelocityInPercentPerSecond"); } + } + + /// + /// Gets the minimum position. + /// + /// The minimum position. + public Vector3Node MinPosition + { + get { return ReferenceProperty("MinPosition"); } + } + + /// + /// Gets the maximum position. + /// + /// The maximum position. + public Vector3Node MaxPosition + { + get { return ReferenceProperty("MaxPosition"); } + } + + /// + /// Gets the natural resting position. + /// + /// The natural resting position. + public Vector3Node NaturalRestingPosition + { + get { return ReferenceProperty("NaturalRestingPosition"); } + } + + /// + /// Gets the position. + /// + /// The position. + public Vector3Node Position + { + get { return ReferenceProperty("Position"); } + } + + /// + /// Gets the position inertia decay rate. + /// + /// The position inertia decay rate. + public Vector3Node PositionInertiaDecayRate + { + get { return ReferenceProperty("PositionInertiaDecayRate"); } + } + + /// + /// Gets the position velocity in pixels per second. + /// + /// The position velocity in pixels per second. + public Vector3Node PositionVelocityInPixelsPerSecond + { + get { return ReferenceProperty("PositionVelocityInPixelsPerSecond"); } + } + } +} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/ManipulationPropertySetReferenceNode.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/ManipulationPropertySetReferenceNode.cs new file mode 100644 index 000000000..ad71b3051 --- /dev/null +++ b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/ManipulationPropertySetReferenceNode.cs @@ -0,0 +1,79 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Windows.UI.Composition; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork +{ + /// + /// Class ManipulationPropertySetReferenceNode. This class cannot be inherited. + /// + /// + public sealed class ManipulationPropertySetReferenceNode : PropertySetReferenceNode + { + /// + /// Initializes a new instance of the class. + /// + /// Name of the parameter. + /// The ps. + internal ManipulationPropertySetReferenceNode(string paramName, CompositionPropertySet ps = null) + : base(paramName, ps) + { + } + + /// + /// Initializes a new instance of the class. + /// Needed for GetSpecializedReference + /// + internal ManipulationPropertySetReferenceNode() + : base(null, null) + { + } + + /// + /// Gets the center point. + /// + /// The center point. + public Vector3Node CenterPoint + { + get { return ReferenceProperty("CenterPoint"); } + } + + /// + /// Gets the pan. + /// + /// The pan. + public Vector3Node Pan + { + get { return ReferenceProperty("Pan"); } + } + + /// + /// Gets the scale. + /// + /// The scale. + public Vector3Node Scale + { + get { return ReferenceProperty("Scale"); } + } + + /// + /// Gets the translation. + /// + /// The translation. + public Vector3Node Translation + { + get { return ReferenceProperty("Translation"); } + } + + /// + /// Gets the matrix. + /// + /// The matrix. + public Matrix4x4Node Matrix + { + get { return ReferenceProperty("Matrix"); } + } + } +} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/NineGridBrushReferenceNode.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/NineGridBrushReferenceNode.cs new file mode 100644 index 000000000..ef9575db6 --- /dev/null +++ b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/NineGridBrushReferenceNode.cs @@ -0,0 +1,109 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Windows.UI.Composition; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork +{ + /// + /// Class NineGridBrushReferenceNode. This class cannot be inherited. + /// + /// + public sealed class NineGridBrushReferenceNode : ReferenceNode + { + /// + /// Initializes a new instance of the class. + /// + /// Name of the parameter. + /// The brush. + internal NineGridBrushReferenceNode(string paramName, CompositionNineGridBrush brush = null) + : base(paramName, brush) + { + } + + /// + /// Creates the target reference. + /// + /// NineGridBrushReferenceNode. + internal static NineGridBrushReferenceNode CreateTargetReference() + { + var node = new NineGridBrushReferenceNode(null); + node.NodeType = ExpressionNodeType.TargetReference; + + return node; + } + + /// + /// Gets the bottom inset. + /// + /// The bottom inset. + public ScalarNode BottomInset + { + get { return ReferenceProperty("BottomInset"); } + } + + /// + /// Gets the bottom inset scale. + /// + /// The bottom inset scale. + public ScalarNode BottomInsetScale + { + get { return ReferenceProperty("BottomInsetScale"); } + } + + /// + /// Gets the left inset. + /// + /// The left inset. + public ScalarNode LeftInset + { + get { return ReferenceProperty("LeftInset"); } + } + + /// + /// Gets the left inset scale. + /// + /// The left inset scale. + public ScalarNode LeftInsetScale + { + get { return ReferenceProperty("LeftInsetScale"); } + } + + /// + /// Gets the right inset. + /// + /// The right inset. + public ScalarNode RightInset + { + get { return ReferenceProperty("RightInset"); } + } + + /// + /// Gets the right inset scale. + /// + /// The right inset scale. + public ScalarNode RightInsetScale + { + get { return ReferenceProperty("RightInsetScale"); } + } + + /// + /// Gets the top inset. + /// + /// The top inset. + public ScalarNode TopInset + { + get { return ReferenceProperty("TopInset"); } + } + + /// + /// Gets the top inset scale. + /// + /// The top inset scale. + public ScalarNode TopInsetScale + { + get { return ReferenceProperty("TopInsetScale"); } + } + } +} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/PointLightReferenceNode.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/PointLightReferenceNode.cs new file mode 100644 index 000000000..e64d570da --- /dev/null +++ b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/PointLightReferenceNode.cs @@ -0,0 +1,91 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Windows.UI.Composition; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork +{ + /// + /// Class PointLightReferenceNode. This class cannot be inherited. + /// + /// + public sealed class PointLightReferenceNode : ReferenceNode + { + /// + /// Initializes a new instance of the class. + /// + /// Name of the parameter. + /// The light. + internal PointLightReferenceNode(string paramName, PointLight light = null) + : base(paramName, light) + { + } + + /// + /// Creates the target reference. + /// + /// PointLightReferenceNode. + internal static PointLightReferenceNode CreateTargetReference() + { + var node = new PointLightReferenceNode(null); + node.NodeType = ExpressionNodeType.TargetReference; + + return node; + } + + /// + /// Gets the constant attenuation. + /// + /// The constant attenuation. + public ScalarNode ConstantAttenuation + { + get { return ReferenceProperty("ConstantAttenuation"); } + } + + /// + /// Gets the linear attenuation. + /// + /// The linear attenuation. + public ScalarNode LinearAttenuation + { + get { return ReferenceProperty("LinearAttenuation"); } + } + + /// + /// Gets the quadratic attenuation. + /// + /// The quadratic attenuation. + public ScalarNode QuadraticAttentuation + { + get { return ReferenceProperty("QuadraticAttentuation"); } + } + + /// + /// Gets the color. + /// + /// The color. + public ColorNode Color + { + get { return ReferenceProperty("Color"); } + } + + /// + /// Gets the direction. + /// + /// The direction. + public Vector3Node Direction + { + get { return ReferenceProperty("Direction"); } + } + + /// + /// Gets the offset. + /// + /// The offset. + public Vector3Node Offset + { + get { return ReferenceProperty("Offset"); } + } + } +} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/PointerPositionPropertySetReferenceNode.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/PointerPositionPropertySetReferenceNode.cs new file mode 100644 index 000000000..968db6d1e --- /dev/null +++ b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/PointerPositionPropertySetReferenceNode.cs @@ -0,0 +1,43 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Windows.UI.Composition; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork +{ + /// + /// Class PointerPositionPropertySetReferenceNode. This class cannot be inherited. + /// + /// + public sealed class PointerPositionPropertySetReferenceNode : PropertySetReferenceNode + { + /// + /// Initializes a new instance of the class. + /// + /// Name of the parameter. + /// The ps. + internal PointerPositionPropertySetReferenceNode(string paramName, CompositionPropertySet ps = null) + : base(paramName, ps) + { + } + + /// + /// Initializes a new instance of the class. + /// Needed for GetSpecializedReference + /// + internal PointerPositionPropertySetReferenceNode() + : base(null, null) + { + } + + /// + /// Gets the position. + /// + /// The position. + public Vector3Node Position + { + get { return ReferenceProperty("Position"); } + } + } +} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/PropertySetReferenceNode.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/PropertySetReferenceNode.cs new file mode 100644 index 000000000..b0f9d132b --- /dev/null +++ b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/PropertySetReferenceNode.cs @@ -0,0 +1,52 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Windows.UI.Composition; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork +{ + /// + /// Class PropertySetReferenceNode. + /// + /// + public class PropertySetReferenceNode : ReferenceNode + { + /// + /// Initializes a new instance of the class. + /// + /// Name of the parameter. + /// The ps. + internal PropertySetReferenceNode(string paramName, CompositionPropertySet ps = null) + : base(paramName, ps) + { + } + + /// + /// Initializes a new instance of the class. + /// + // Needed for GetSpecializedReference<>() + internal PropertySetReferenceNode() + : base(null, null) + { + } + + /// + /// Gets or sets the source. + /// + /// The source. + internal CompositionPropertySet Source { get; set; } + + /// + /// Creates the target reference. + /// + /// PropertySetReferenceNode. + internal static PropertySetReferenceNode CreateTargetReference() + { + var node = new PropertySetReferenceNode(null); + node.NodeType = ExpressionNodeType.TargetReference; + + return node; + } + } +} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/ReferenceNode.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/ReferenceNode.cs new file mode 100644 index 000000000..aeb180862 --- /dev/null +++ b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/ReferenceNode.cs @@ -0,0 +1,168 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Windows.UI.Composition; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork +{ + /// + /// Class ReferenceNode. + /// + /// + public abstract class ReferenceNode : ExpressionNode + { + /// + /// Initializes a new instance of the class. + /// + /// Name of the parameter. + /// The comp object. + internal ReferenceNode(string paramName, CompositionObject compObj = null) + { + Reference = compObj; + NodeType = ExpressionNodeType.Reference; + ParamName = paramName; + } + + /// + /// Gets the reference. + /// + /// The reference. + public CompositionObject Reference { get; private set; } + + /// + /// Create a reference to the specified boolean property. This maybe be a property on the CompositionObject directly, or on the its PropertySet. + /// + /// The name of the property to reference. + /// BooleanNode. + public BooleanNode GetBooleanProperty(string propertyName) + { + return ReferenceProperty(propertyName); + } + + /// + /// Create a reference to the specified float property. This maybe be a property on the CompositionObject directly, or on the its PropertySet. + /// + /// The name of the property to reference. + /// ScalarNode + public ScalarNode GetScalarProperty(string propertyName) + { + return ReferenceProperty(propertyName); + } + + /// + /// Create a reference to the specified Vector2 property. This maybe be a property on the CompositionObject directly, or on the its PropertySet. + /// + /// The name of the property to reference. + /// Vector2Node + public Vector2Node GetVector2Property(string propertyName) + { + return ReferenceProperty(propertyName); + } + + /// + /// Create a reference to the specified Vector3 property. This maybe be a property on the CompositionObject directly, or on the its PropertySet. + /// + /// The name of the property to reference. + /// Vector3Node + public Vector3Node GetVector3Property(string propertyName) + { + return ReferenceProperty(propertyName); + } + + /// + /// Create a reference to the specified Vector4 property. This maybe be a property on the CompositionObject directly, or on the its PropertySet. + /// + /// The name of the property to reference. + /// Vector4Node + public Vector4Node GetVector4Property(string propertyName) + { + return ReferenceProperty(propertyName); + } + + /// + /// Create a reference to the specified Color property. This maybe be a property on the CompositionObject directly, or on the its PropertySet. + /// + /// The name of the property to reference. + /// ColorNode + public ColorNode GetColorProperty(string propertyName) + { + return ReferenceProperty(propertyName); + } + + /// + /// Create a reference to the specified Quaternion property. This maybe be a property on the CompositionObject directly, or on the its PropertySet. + /// + /// The name of the property to reference. + /// QuaternionNode + public QuaternionNode GetQuaternionProperty(string propertyName) + { + return ReferenceProperty(propertyName); + } + + /// + /// Create a reference to the specified Matrix3x2 property. This maybe be a property on the CompositionObject directly, or on the its PropertySet. + /// + /// The name of the property to reference. + /// Matrix3x2Node + public Matrix3x2Node GetMatrix3x2Property(string propertyName) + { + return ReferenceProperty(propertyName); + } + + /// + /// Create a reference to the specified Matrix4x4 property. This maybe be a property on the CompositionObject directly, or on the its PropertySet. + /// + /// The name of the property to reference. + /// Matrix4x4Node + public Matrix4x4Node GetMatrix4x4Property(string propertyName) + { + return ReferenceProperty(propertyName); + } + + /// + /// Gets the reference parameter string. + /// + /// System.String. + internal string GetReferenceParamString() + { + if (NodeType == ExpressionNodeType.TargetReference) + { + return "this.target"; + } + else + { + return ParamName; + } + } + + /// + /// References the property. + /// + /// A class that derives from ExpressionNode. + /// Name of the property. + /// T. + protected internal T ReferenceProperty(string propertyName) + where T : ExpressionNode + { + T newNode = ExpressionNode.CreateExpressionNode(); + + (newNode as ExpressionNode).NodeType = ExpressionNodeType.ReferenceProperty; + (newNode as ExpressionNode).Children.Add(this); + (newNode as ExpressionNode).PropertyName = propertyName; + + return newNode; + } + + /// + /// Gets the value. + /// + /// System.String. + /// GetValue is not implemented for ReferenceNode and shouldn't be called + protected internal override string GetValue() + { + throw new NotImplementedException("GetValue is not implemented for ReferenceNode and shouldn't be called"); + } + } +} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/SpotLightReferenceNode.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/SpotLightReferenceNode.cs new file mode 100644 index 000000000..b0530064d --- /dev/null +++ b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/SpotLightReferenceNode.cs @@ -0,0 +1,145 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Windows.UI.Composition; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork +{ + /// + /// Class SpotLightReferenceNode. This class cannot be inherited. + /// + /// + public sealed class SpotLightReferenceNode : ReferenceNode + { + /// + /// Initializes a new instance of the class. + /// + /// Name of the parameter. + /// The light. + internal SpotLightReferenceNode(string paramName, SpotLight light = null) + : base(paramName, light) + { + } + + /// + /// Creates the target reference. + /// + /// SpotLightReferenceNode. + internal static SpotLightReferenceNode CreateTargetReference() + { + var node = new SpotLightReferenceNode(null); + node.NodeType = ExpressionNodeType.TargetReference; + + return node; + } + + /// + /// Gets the constant attenuation. + /// + /// The constant attenuation. + public ScalarNode ConstantAttenuation + { + get { return ReferenceProperty("ConstantAttenuation"); } + } + + /// + /// Gets the linear attenuation. + /// + /// The linear attenuation. + public ScalarNode LinearAttenuation + { + get { return ReferenceProperty("LinearAttenuation"); } + } + + /// + /// Gets the quadratic attenuation. + /// + /// The quadratic attenuation. + public ScalarNode QuadraticAttentuation + { + get { return ReferenceProperty("QuadraticAttentuation"); } + } + + /// + /// Gets the inner cone angle. + /// + /// The inner cone angle. + public ScalarNode InnerConeAngle + { + get { return ReferenceProperty("InnerConeAngle"); } + } + + /// + /// Gets the inner cone angle in degrees. + /// + /// The inner cone angle in degrees. + public ScalarNode InnerConeAngleInDegrees + { + get { return ReferenceProperty("InnerConeAngleInDegrees"); } + } + + /// + /// Gets the outer cone angle. + /// + /// The outer cone angle. + public ScalarNode OuterConeAngle + { + get { return ReferenceProperty("OuterConeAngle"); } + } + + /// + /// Gets the outer cone angle in degrees. + /// + /// The outer cone angle in degrees. + public ScalarNode OuterConeAngleInDegrees + { + get { return ReferenceProperty("OuterConeAngleInDegrees"); } + } + + /// + /// Gets the color. + /// + /// The color. + public ColorNode Color + { + get { return ReferenceProperty("Color"); } + } + + /// + /// Gets the color of the inner cone. + /// + /// The color of the inner cone. + public ColorNode InnerConeColor + { + get { return ReferenceProperty("InnerConeColor"); } + } + + /// + /// Gets the color of the outer cone. + /// + /// The color of the outer cone. + public ColorNode OuterConeColor + { + get { return ReferenceProperty("OuterConeColor"); } + } + + /// + /// Gets the direction. + /// + /// The direction. + public Vector3Node Direction + { + get { return ReferenceProperty("Direction"); } + } + + /// + /// Gets the offset. + /// + /// The offset. + public Vector3Node Offset + { + get { return ReferenceProperty("Offset"); } + } + } +} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/SurfaceBrushReferenceNode.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/SurfaceBrushReferenceNode.cs new file mode 100644 index 000000000..a5b35cdae --- /dev/null +++ b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/SurfaceBrushReferenceNode.cs @@ -0,0 +1,154 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Windows.UI.Composition; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork +{ + /// + /// Class SurfaceBrushReferenceNode. This class cannot be inherited. + /// + /// + public sealed class SurfaceBrushReferenceNode : ReferenceNode + { + /// + /// Initializes a new instance of the class. + /// + /// Name of the parameter. + /// The brush. + internal SurfaceBrushReferenceNode(string paramName, CompositionSurfaceBrush brush = null) + : base(paramName, brush) + { + } + + /// + /// Creates the target reference. + /// + /// SurfaceBrushReferenceNode. + internal static SurfaceBrushReferenceNode CreateTargetReference() + { + var node = new SurfaceBrushReferenceNode(null); + node.NodeType = ExpressionNodeType.TargetReference; + + return node; + } + + /// + /// Gets the horizontal alignment ratio. + /// + /// The horizontal alignment ratio. + public ScalarNode HorizontalAlignmentRatio + { + get { return ReferenceProperty("HorizontalAlignmentRatio"); } + } + + /// + /// Gets the vertical alignment ratio. + /// + /// The vertical alignment ratio. + public ScalarNode VerticalAlignmentRatio + { + get { return ReferenceProperty("VerticalAlignmentRatio"); } + } + + /// + /// Gets the bottom inset. + /// + /// The bottom inset. + public ScalarNode BottomInset + { + get { return ReferenceProperty("BottomInset"); } + } + + /// + /// Gets the left inset. + /// + /// The left inset. + public ScalarNode LeftInset + { + get { return ReferenceProperty("LeftInset"); } + } + + /// + /// Gets the right inset. + /// + /// The right inset. + public ScalarNode RightInset + { + get { return ReferenceProperty("RightInset"); } + } + + /// + /// Gets the top inset. + /// + /// The top inset. + public ScalarNode TopInset + { + get { return ReferenceProperty("TopInset"); } + } + + /// + /// Gets the rotation angle. + /// + /// The rotation angle. + public ScalarNode RotationAngle + { + get { return ReferenceProperty("RotationAngle"); } + } + + /// + /// Gets the rotation angle in degrees. + /// + /// The rotation angle in degrees. + public ScalarNode RotationAngleInDegrees + { + get { return ReferenceProperty("RotationAngleInDegrees"); } + } + + /// + /// Gets the anchor point. + /// + /// The anchor point. + public Vector2Node AnchorPoint + { + get { return ReferenceProperty("AnchorPoint"); } + } + + /// + /// Gets the center point. + /// + /// The center point. + public Vector2Node CenterPoint + { + get { return ReferenceProperty("CenterPoint"); } + } + + /// + /// Gets the offset. + /// + /// The offset. + public Vector2Node Offset + { + get { return ReferenceProperty("Offset"); } + } + + /// + /// Gets the scale. + /// + /// The scale. + public Vector2Node Scale + { + get { return ReferenceProperty("Scale"); } + } + + /// + /// Gets the transform matrix. + /// + /// The transform matrix. + public Matrix3x2Node TransformMatrix + { + get { return ReferenceProperty("TransformMatrix"); } + } + } +} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/VisualReferenceNode.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/VisualReferenceNode.cs new file mode 100644 index 000000000..f324aed88 --- /dev/null +++ b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/VisualReferenceNode.cs @@ -0,0 +1,162 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Windows.UI.Composition; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork +{ + /// + /// Class VisualReferenceNode. This class cannot be inherited. + /// + /// + public sealed class VisualReferenceNode : ReferenceNode + { + /// + /// Initializes a new instance of the class. + /// + /// Name of the parameter. + /// The v. + internal VisualReferenceNode(string paramName, Visual v = null) + : base(paramName, v) + { + } + + /// + /// Creates the target reference. + /// + /// VisualReferenceNode. + internal static VisualReferenceNode CreateTargetReference() + { + var node = new VisualReferenceNode(null); + node.NodeType = ExpressionNodeType.TargetReference; + + return node; + } + + /// + /// Gets the opacity. + /// + /// The opacity. + public ScalarNode Opacity + { + get { return ReferenceProperty("Opacity"); } + } + + /// + /// Gets the rotation angle. + /// + /// The rotation angle. + public ScalarNode RotationAngle + { + get { return ReferenceProperty("RotationAngle"); } + } + + /// + /// Gets the rotation angle in degrees. + /// + /// The rotation angle in degrees. + public ScalarNode RotationAngleInDegrees + { + get { return ReferenceProperty("RotationAngleInDegrees"); } + } + + /// + /// Gets the anchor point. + /// + /// The anchor point. + public Vector2Node AnchorPoint + { + get { return ReferenceProperty("AnchorPoint"); } + } + + /// + /// Gets the size of the relative. + /// + /// The size of the relative. + public Vector2Node RelativeSize + { + get { return ReferenceProperty("RelativeSize"); } + } + + /// + /// Gets the size. + /// + /// The size. + public Vector2Node Size + { + get { return ReferenceProperty("Size"); } + } + + /// + /// Gets the center point. + /// + /// The center point. + public Vector3Node CenterPoint + { + get { return ReferenceProperty("CenterPoint"); } + } + + /// + /// Gets the offset. + /// + /// The offset. + public Vector3Node Offset + { + get { return ReferenceProperty("Offset"); } + } + + /// + /// Gets the relative offset. + /// + /// The relative offset. + public Vector3Node RelativeOffset + { + get { return ReferenceProperty("RelativeOffset"); } + } + + /// + /// Gets the rotation axis. + /// + /// The rotation axis. + public Vector3Node RotationAxis + { + get { return ReferenceProperty("RotationAxis"); } + } + + /// + /// Gets the scale. + /// + /// The scale. + public Vector3Node Scale + { + get { return ReferenceProperty("Scale"); } + } + + /// + /// Gets the Translation. + /// + public Vector3Node Translation + { + get { return GetVector3Property("Translation"); } + } + + /// + /// Gets the orientation. + /// + /// The orientation. + public QuaternionNode Orientation + { + get { return ReferenceProperty("Orientation"); } + } + + /// + /// Gets the transform matrix. + /// + /// The transform matrix. + public Matrix4x4Node TransformMatrix + { + get { return ReferenceProperty("TransformMatrix"); } + } + } +} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/ExpressionsFork.csproj b/labs/CompositionCollectionView/ExpressionsFork/ExpressionsFork.csproj new file mode 100644 index 000000000..95660eade --- /dev/null +++ b/labs/CompositionCollectionView/ExpressionsFork/ExpressionsFork.csproj @@ -0,0 +1,183 @@ + + + + + Debug + AnyCPU + {1E97AC9F-CB43-4B98-AEF9-2BA035E037A7} + Library + Properties + ExpressionsFork + ExpressionsFork + en-US + UAP + 10.0.22000.0 + 10.0.17763.0 + 14 + 512 + {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + disable + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + prompt + 4 + true + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + prompt + 4 + + + x86 + true + bin\x86\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + false + prompt + + + x86 + bin\x86\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + false + prompt + + + ARM + true + bin\ARM\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + false + prompt + + + ARM + bin\ARM\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + false + prompt + + + ARM64 + true + bin\ARM64\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + false + prompt + + + ARM64 + bin\ARM64\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + false + prompt + + + x64 + true + bin\x64\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + false + prompt + + true + + + x64 + bin\x64\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + false + prompt + + + PackageReference + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 6.2.11 + + + + 14.0 + + + + \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Properties/AssemblyInfo.cs b/labs/CompositionCollectionView/ExpressionsFork/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..6f32dca70 --- /dev/null +++ b/labs/CompositionCollectionView/ExpressionsFork/Properties/AssemblyInfo.cs @@ -0,0 +1,29 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("ExpressionsFork")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("ExpressionsFork")] +[assembly: AssemblyCopyright("Copyright © 2022")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: ComVisible(false)] \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Properties/ExpressionsFork.rd.xml b/labs/CompositionCollectionView/ExpressionsFork/Properties/ExpressionsFork.rd.xml new file mode 100644 index 000000000..b824333d1 --- /dev/null +++ b/labs/CompositionCollectionView/ExpressionsFork/Properties/ExpressionsFork.rd.xml @@ -0,0 +1,33 @@ + + + + + + + + + diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/BackedTemplatedControlSample.xaml b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/BackedTemplatedControlSample.xaml new file mode 100644 index 000000000..5736057be --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/BackedTemplatedControlSample.xaml @@ -0,0 +1,17 @@ + + + + + + + diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/BackedTemplatedControlSample.xaml.cs b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/BackedTemplatedControlSample.xaml.cs new file mode 100644 index 000000000..ed1dd2f78 --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/BackedTemplatedControlSample.xaml.cs @@ -0,0 +1,24 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace CompositionCollectionView.Sample; + +[ToolkitSampleBoolOption("IsTextVisible", "IsVisible", true)] +// Single values without a colon are used for both label and value. +// To provide a different label for the value, separate with a colon surrounded by a single space on both sides ("label : value"). +[ToolkitSampleMultiChoiceOption("TextSize", title: "Text size", "Small : 12", "Normal : 16", "Big : 32")] +[ToolkitSampleMultiChoiceOption("TextFontFamily", title: "Font family", "Segoe UI", "Arial", "Consolas")] +[ToolkitSampleMultiChoiceOption("TextForeground", title: "Text foreground", + "Teal : #0ddc8c", + "Sand : #e7a676", + "Dull green : #5d7577")] + +[ToolkitSample(id: nameof(BackedCompositionCollectionViewControlSample), "Backed templated control", description: "A sample for showing how to create and use a templated control with a backed resource dictionary.")] +public sealed partial class BackedCompositionCollectionViewControlSample : Page +{ + public BackedCompositionCollectionViewControlSample() + { + this.InitializeComponent(); + } +} diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/BackedTemplatedControlWithCustomStyleSample.xaml b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/BackedTemplatedControlWithCustomStyleSample.xaml new file mode 100644 index 000000000..a60fa2706 --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/BackedTemplatedControlWithCustomStyleSample.xaml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/BackedTemplatedControlWithCustomStyleSample.xaml.cs b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/BackedTemplatedControlWithCustomStyleSample.xaml.cs new file mode 100644 index 000000000..46bb5a5f7 --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/BackedTemplatedControlWithCustomStyleSample.xaml.cs @@ -0,0 +1,24 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace CompositionCollectionView.Sample; + +[ToolkitSampleBoolOption("IsTextVisible", "IsVisible", true)] +// Single values without a colon are used for both label and value. +// To provide a different label for the value, separate with a colon surrounded by a single space on both sides ("label : value"). +[ToolkitSampleMultiChoiceOption("TextSize", title: "Text size", "Small : 12", "Normal : 16", "Big : 32")] +[ToolkitSampleMultiChoiceOption("TextFontFamily", title: "Font family", "Segoe UI", "Arial", "Consolas")] +[ToolkitSampleMultiChoiceOption("TextForeground", title: "Text foreground", + "Teal : #0ddc8c", + "Sand : #e7a676", + "Dull green : #5d7577")] + +[ToolkitSample(id: nameof(BackedTemplatedControlWithCustomStyleSample), "Backed templated control (restyled)", description: "A sample for showing how to create and use a templated control with a backed resource dictionary and a custom style.")] +public sealed partial class BackedTemplatedControlWithCustomStyleSample : Page +{ + public BackedTemplatedControlWithCustomStyleSample() + { + this.InitializeComponent(); + } +} diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/CompositionCollectionView.Sample.csproj b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/CompositionCollectionView.Sample.csproj new file mode 100644 index 000000000..36ad38b8f --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/CompositionCollectionView.Sample.csproj @@ -0,0 +1,31 @@ + + + + + + + + %(Filename) + + + + + + + + + + + + + + + + + + + + + + + diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/CompositionCollectionView.md b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/CompositionCollectionView.md new file mode 100644 index 000000000..93df9773f --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/CompositionCollectionView.md @@ -0,0 +1,32 @@ +--- +title: CompositionCollectionView +author: githubaccount +description: TODO: Your experiment's description here +keywords: CompositionCollectionView, Control, Layout +dev_langs: + - csharp +category: Controls +subcategory: Layout +--- + + + + + + + +# CompositionCollectionView + +For more information about this experiment see: +- Discussion: TODO: PASTE LINK HERE +- Issue: TODO: PASTE LINK HERE + +TODO: Fill in information about this experiment and how to get started here... + + +# Templated Controls +### Implict style + +> [!SAMPLE CompositionCollectionViewFirstSamplePage] + + diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/CompositionCollectionViewFirstSamplePage.xaml b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/CompositionCollectionViewFirstSamplePage.xaml new file mode 100644 index 000000000..254a05237 --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/CompositionCollectionViewFirstSamplePage.xaml @@ -0,0 +1,19 @@ + + + + Hello sdgsag + + + + diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/CompositionCollectionViewFirstSamplePage.xaml.cs b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/CompositionCollectionViewFirstSamplePage.xaml.cs new file mode 100644 index 000000000..c5b6d823c --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/CompositionCollectionViewFirstSamplePage.xaml.cs @@ -0,0 +1,91 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using CommunityToolkit.Labs.Core.SourceGenerators; +using CommunityToolkit.Labs.Core.SourceGenerators.Attributes; +using CommunityToolkit.Labs.WinUI.CompositionCollectionView; +using Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork; + +#if !WINAPPSDK +using Windows.Foundation; +using Windows.Foundation.Collections; +using Windows.UI.Composition; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Controls.Primitives; +using Windows.UI.Xaml.Data; +using Windows.UI.Xaml.Input; +using Windows.UI.Xaml.Media; +using Windows.UI.Xaml.Navigation; +using Windows.UI.Xaml.Shapes; +#else +using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Controls; +using Microsoft.UI.Xaml.Controls.Primitives; +using Microsoft.UI.Xaml.Data; +using Microsoft.UI.Xaml.Input; +using Microsoft.UI.Xaml.Media; +using Microsoft.UI.Xaml.Navigation; +#endif + + +namespace CompositionCollectionView.Sample +{ + [ToolkitSampleBoolOption("IsTextVisible", "IsVisible", true)] + // Single values without a colon are used for both label and value. + // To provide a different label for the value, separate with a colon surrounded by a single space on both sides ("label : value"). + [ToolkitSampleMultiChoiceOption("TextSize", title: "Text size", "Small : 12", "Normal : 16", "Big : 32")] + [ToolkitSampleMultiChoiceOption("TextFontFamily", title: "Font family", "Segoe UI", "Arial", "Consolas")] + [ToolkitSampleMultiChoiceOption("TextForeground", title: "Text foreground", + "Teal : #0ddc8c", + "Sand : #e7a676", + "Dull green : #5d7577")] + + [ToolkitSample(id: nameof(CompositionCollectionViewFirstSamplePage), "Simple Options", description: "A sample page for showing how to do simple options.")] + public sealed partial class CompositionCollectionViewFirstSamplePage : Page + { + public CompositionCollectionViewFirstSamplePage() + { + this.InitializeComponent(); + + var layout = new SampleLayout((id) => + new Rectangle() { + Width = 100, + Height = 100, + Fill = new SolidColorBrush(Windows.UI.Colors.BlueViolet) + } + , (_) => { }); + compositionCollectionView.SetLayout(layout); + compositionCollectionView.UpdateSource(new List<(uint, Action>)>() + { + (0, (_,_)=>{ }), + (1, (_,_)=>{ }), + (2, (_,_)=>{ }), + (3, (_,_)=>{ }) + }); + } + + public class SampleLayout : Layout + { + public SampleLayout(Func elementFactory, Action? log) : base(elementFactory, log) + { + } + + public override Vector3Node GetElementPositionNode(ElementReference element) + { + return ExpressionFunctions.Vector3(element.Id * 120, 0, 0); + } + + public override ScalarNode GetElementScaleNode(ElementReference element) => 1; + + protected override void ConfigureElement(ElementReference element) + { + } + + public override void UpdateElement(ElementReference element) + { + } + } + } +} diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/TemplatedControlSample.xaml b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/TemplatedControlSample.xaml new file mode 100644 index 000000000..17bf8b537 --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/TemplatedControlSample.xaml @@ -0,0 +1,17 @@ + + + + + + + diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/TemplatedControlSample.xaml.cs b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/TemplatedControlSample.xaml.cs new file mode 100644 index 000000000..68c944954 --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/TemplatedControlSample.xaml.cs @@ -0,0 +1,24 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace CompositionCollectionView.Sample; + +[ToolkitSampleBoolOption("IsTextVisible", "IsVisible", true)] +// Single values without a colon are used for both label and value. +// To provide a different label for the value, separate with a colon surrounded by a single space on both sides ("label : value"). +[ToolkitSampleMultiChoiceOption("TextSize", title: "Text size", "Small : 12", "Normal : 16", "Big : 32")] +[ToolkitSampleMultiChoiceOption("TextFontFamily", title: "Font family", "Segoe UI", "Arial", "Consolas")] +[ToolkitSampleMultiChoiceOption("TextForeground", title: "Text foreground", + "Teal : #0ddc8c", + "Sand : #e7a676", + "Dull green : #5d7577")] + +[ToolkitSample(id: nameof(CompositionCollectionViewControlSample), "Templated control", description: "A sample for showing how to create and use a templated control.")] +public sealed partial class CompositionCollectionViewControlSample : Page +{ + public CompositionCollectionViewControlSample() + { + this.InitializeComponent(); + } +} diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/TemplatedControlWithCustomStyleSample.xaml b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/TemplatedControlWithCustomStyleSample.xaml new file mode 100644 index 000000000..aee6d0d98 --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/TemplatedControlWithCustomStyleSample.xaml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/TemplatedControlWithCustomStyleSample.xaml.cs b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/TemplatedControlWithCustomStyleSample.xaml.cs new file mode 100644 index 000000000..f413d2a9c --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/TemplatedControlWithCustomStyleSample.xaml.cs @@ -0,0 +1,24 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace CompositionCollectionView.Sample; + +[ToolkitSampleBoolOption("IsTextVisible", "IsVisible", true)] +// Single values without a colon are used for both label and value. +// To provide a different label for the value, separate with a colon surrounded by a single space on both sides ("label : value"). +[ToolkitSampleMultiChoiceOption("TextSize", title: "Text size", "Small : 12", "Normal : 16", "Big : 32")] +[ToolkitSampleMultiChoiceOption("TextFontFamily", title: "Font family", "Segoe UI", "Arial", "Consolas")] +[ToolkitSampleMultiChoiceOption("TextForeground", title: "Text foreground", + "Teal : #0ddc8c", + "Sand : #e7a676", + "Dull green : #5d7577")] + +[ToolkitSample(id: nameof(TemplatedControlWithCustomStyleSample), "Templated control (restyled)", description: "A sample for showing how to create a use and templated control with a custom style.")] +public sealed partial class TemplatedControlWithCustomStyleSample : Page +{ + public TemplatedControlWithCustomStyleSample() + { + this.InitializeComponent(); + } +} diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Uwp/CompositionCollectionView.Uwp.csproj b/labs/CompositionCollectionView/samples/CompositionCollectionView.Uwp/CompositionCollectionView.Uwp.csproj new file mode 100644 index 000000000..c5dcc58be --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Uwp/CompositionCollectionView.Uwp.csproj @@ -0,0 +1,32 @@ + + + + + + + CompositionCollectionView.Uwp + CompositionCollectionView.Uwp + {052083DA-908D-40A3-AD89-DCD26450A34C} + + + + + + + + + + Designer + + + + + {30FD6398-9706-434D-8A23-088E2AAEDD11} + CommunityToolkit.Labs.WinUI.CompositionCollectionView + + + {B521DDDD-EC8E-4BF8-B15F-AAD7E430A5CB} + CompositionCollectionView.Sample + + + \ No newline at end of file diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Uwp/Package.appxmanifest b/labs/CompositionCollectionView/samples/CompositionCollectionView.Uwp/Package.appxmanifest new file mode 100644 index 000000000..7b99aac74 --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Uwp/Package.appxmanifest @@ -0,0 +1,49 @@ + + + + + + + + + + CommunityToolkit Labs: CompositionCollectionView Sample + CommunityToolkit + Assets\StoreLogo.png + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Uwp/Properties/AssemblyInfo.cs b/labs/CompositionCollectionView/samples/CompositionCollectionView.Uwp/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..0851e6170 --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Uwp/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("CommunityToolkit.Labs.Uwp.Samples.CompositionCollectionView")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany(".NET Foundation")] +[assembly: AssemblyProduct("CommunityToolkit.Labs.Uwp.Samples.CompositionCollectionView")] +[assembly: AssemblyCopyright("Copyright © .NET Foundation 2022")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: ComVisible(false)] diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Uwp/Properties/Default.rd.xml b/labs/CompositionCollectionView/samples/CompositionCollectionView.Uwp/Properties/Default.rd.xml new file mode 100644 index 000000000..af00722cd --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Uwp/Properties/Default.rd.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/CompositionCollectionView.Wasm.csproj b/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/CompositionCollectionView.Wasm.csproj new file mode 100644 index 000000000..d037820ae --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/CompositionCollectionView.Wasm.csproj @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/Program.cs b/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/Program.cs new file mode 100644 index 000000000..54d7d4bf4 --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/Program.cs @@ -0,0 +1,19 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using CommunityToolkit.Labs.Shared; + +namespace CompositionCollectionView.Wasm; + +public class Program +{ + private static App? _app; + + static int Main(string[] args) + { + Application.Start(_ => _app = new App()); + + return 0; + } +} diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/Properties/launchSettings.json b/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/Properties/launchSettings.json new file mode 100644 index 000000000..958758b84 --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/Properties/launchSettings.json @@ -0,0 +1,27 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:51668/", + "sslPort": 44381 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "CompositionCollectionView.Wasm": { + "commandName": "Project", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "https://localhost:5001;http://localhost:5000" + } + } +} diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/WasmCSS/Fonts.css b/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/WasmCSS/Fonts.css new file mode 100644 index 000000000..56618162a --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/WasmCSS/Fonts.css @@ -0,0 +1,27 @@ +/** + When adding fonts here, make sure to add them using a base64 data uri, otherwise + fonts loading are delayed, and text may get displayed incorrectly. +*/ + +@font-face { + font-family: "Symbols"; + /* uno-fluentui-assets.woff2 */ + src: url(data:application/x-font-woff;charset=utf-8;base64,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)format('woff'); +} + + +/* Workaround for uno issue https://github.com/unoplatform/uno/issues/693 */ +body::before { + font-family: 'Symbols'; + background: transparent; + content: ""; + opacity: 0; + pointer-events: none; + position: absolute; +} + +/* https://github.com/unoplatform/uno/issues/4304 */ +@font-face { + font-family: 'Segoe UI'; + src: local('system-ui'), local('Segoe UI'), local('-apple-system'), local('BlinkMacSystemFont'), local('Inter'), local('Cantarell'), local('Ubuntu'), local('Roboto'), local('Open Sans'), local('Noto Sans'), local('Helvetica Neue'), local('sans-serif'); +} \ No newline at end of file diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/WasmScripts/AppManifest.js b/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/WasmScripts/AppManifest.js new file mode 100644 index 000000000..51d4b97f8 --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/WasmScripts/AppManifest.js @@ -0,0 +1,5 @@ +var UnoAppManifest = { + splashScreenImage: "Assets/SplashScreen.scale-200.png", + splashScreenColor: "#fff", + displayName: "Labs: CompositionCollectionView" +} diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/wwwroot/web.config b/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/wwwroot/web.config new file mode 100644 index 000000000..8f5a860f5 --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/wwwroot/web.config @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.WinAppSdk/CompositionCollectionView.WinAppSdk.csproj b/labs/CompositionCollectionView/samples/CompositionCollectionView.WinAppSdk/CompositionCollectionView.WinAppSdk.csproj new file mode 100644 index 000000000..b6246939d --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.WinAppSdk/CompositionCollectionView.WinAppSdk.csproj @@ -0,0 +1,27 @@ + + + + + + CompositionCollectionView.WinAppSdk + app.manifest + + + + + + + + + + + + + + + + + + diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.WinAppSdk/Package.appxmanifest b/labs/CompositionCollectionView/samples/CompositionCollectionView.WinAppSdk/Package.appxmanifest new file mode 100644 index 000000000..335dec29f --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.WinAppSdk/Package.appxmanifest @@ -0,0 +1,49 @@ + + + + + + + + CommunityToolkit Labs: CompositionCollectionView Sample + CommunityToolkit + Assets\StoreLogo.png + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.WinAppSdk/Properties/launchSettings.json b/labs/CompositionCollectionView/samples/CompositionCollectionView.WinAppSdk/Properties/launchSettings.json new file mode 100644 index 000000000..f06823289 --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.WinAppSdk/Properties/launchSettings.json @@ -0,0 +1,10 @@ +{ + "profiles": { + "Local machine (Packaged)": { + "commandName": "MsixPackage" + }, + "Local machine (Unpackaged)": { + "commandName": "Project" + } + } +} \ No newline at end of file diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.WinAppSdk/app.manifest b/labs/CompositionCollectionView/samples/CompositionCollectionView.WinAppSdk/app.manifest new file mode 100644 index 000000000..04ff2978a --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.WinAppSdk/app.manifest @@ -0,0 +1,15 @@ + + + + + + + + true/PM + PerMonitorV2, PerMonitor + + + diff --git a/labs/CompositionCollectionView/src/AdditionalAssemblyInfo.cs b/labs/CompositionCollectionView/src/AdditionalAssemblyInfo.cs new file mode 100644 index 000000000..a2179b5cc --- /dev/null +++ b/labs/CompositionCollectionView/src/AdditionalAssemblyInfo.cs @@ -0,0 +1,13 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Runtime.CompilerServices; + +// These `InternalsVisibleTo` calls are intended to make it easier for +// for any internal code to be testable in all the different test projects +// used with the Labs infrastructure. +[assembly: InternalsVisibleTo("CompositionCollectionView.UnitTests.Uwp")] +[assembly: InternalsVisibleTo("CompositionCollectionView.UnitTests.WinAppSdk")] +[assembly: InternalsVisibleTo("CommunityToolkit.Labs.UnitTests.Uwp")] +[assembly: InternalsVisibleTo("CommunityToolkit.Labs.UnitTests.WinAppSdk")] diff --git a/labs/CompositionCollectionView/src/AnimatableCompositionNodeSet.cs b/labs/CompositionCollectionView/src/AnimatableCompositionNodeSet.cs new file mode 100644 index 000000000..4738dd1fa --- /dev/null +++ b/labs/CompositionCollectionView/src/AnimatableCompositionNodeSet.cs @@ -0,0 +1,97 @@ +#nullable enable +using System.Numerics; +using Windows.UI.Composition; + +namespace CommunityToolkit.Labs.WinUI.CompositionCollectionView; +public class AnimatableCompositionNodeSet : IDisposable +{ + private Dictionary _nodes = new(); + private Compositor _compositor; + + private bool disposedValue; + + public AnimatableCompositionNodeSet(Compositor compositor) + { + _compositor = compositor; + } + + public AnimatableScalarCompositionNode GetOrCreateScalarNode(string id, float defaultValue) + { + if (_nodes.ContainsKey(id)) + { + if (_nodes[id] is AnimatableScalarCompositionNode node) + { + return node; + } + else + { + throw new InvalidCastException("Node {id} is not a scalar node"); + } + } + else + { + var newNode = new AnimatableScalarCompositionNode(_compositor); + newNode.Value = defaultValue; + _nodes[id] = newNode; + return newNode; + } + } + + public AnimatableVector3CompositionNode GetOrCreateVector3Node(string id, Vector3 defaultValue) + { + if (_nodes.ContainsKey(id)) + { + if (_nodes[id] is AnimatableVector3CompositionNode node) + { + return node; + } + else + { + throw new InvalidCastException("Node {id} is not a vector3 node"); + } + } + else + { + var newNode = new AnimatableVector3CompositionNode(_compositor); + newNode.Value = defaultValue; + _nodes[id] = newNode; + return newNode; + } + } + + protected virtual void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + // TODO: dispose managed state (managed objects) + foreach (var node in _nodes) + { + if (node.Value is IDisposable disposable) + { + disposable.Dispose(); + } + } + } + + // TODO: free unmanaged resources (unmanaged objects) and override finalizer + // TODO: set large fields to null + disposedValue = true; + } + } + + // // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources + // ~AnimatableScalarCompositionNode() + // { + // // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + // Dispose(disposing: false); + // } + + public void Dispose() + { + // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + Dispose(disposing: true); + GC.SuppressFinalize(this); + } +} diff --git a/labs/CompositionCollectionView/src/AnimatableScalarCompositionNode.cs b/labs/CompositionCollectionView/src/AnimatableScalarCompositionNode.cs new file mode 100644 index 000000000..58a96a408 --- /dev/null +++ b/labs/CompositionCollectionView/src/AnimatableScalarCompositionNode.cs @@ -0,0 +1,65 @@ +#nullable enable +#if !WINAPPSDK +using System.Numerics; +using Windows.UI.Composition; +using static CommunityToolkit.Labs.WinUI.CompositionCollectionView.AnimationConstants; + + +namespace CommunityToolkit.Labs.WinUI.CompositionCollectionView; + +public class AnimatableScalarCompositionNode : IDisposable +{ + private Visual _underlyingVisual; + private bool disposedValue; + + public float Value { get => _underlyingVisual.Offset.X; set => _underlyingVisual.Offset = new Vector3(value, 0, 0); } + + + public AnimatableScalarCompositionNode(Compositor compositor) + { + _underlyingVisual = compositor.CreateShapeVisual(); + } + + public void Animate(CompositionAnimation animation) + { + _underlyingVisual.StartAnimation(Offset.X, animation); + } + + public void Animate(ExpressionNode animation) + { + _underlyingVisual.StartAnimation(Offset.X, animation); + } + + public ScalarNode Reference { get => _underlyingVisual.GetReference().Offset.X; } + + protected virtual void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + // TODO: dispose managed state (managed objects) + _underlyingVisual.Dispose(); + } + + // TODO: free unmanaged resources (unmanaged objects) and override finalizer + // TODO: set large fields to null + disposedValue = true; + } + } + + // // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources + // ~AnimatableScalarCompositionNode() + // { + // // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + // Dispose(disposing: false); + // } + + public void Dispose() + { + // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + Dispose(disposing: true); + GC.SuppressFinalize(this); + } +} +#endif diff --git a/labs/CompositionCollectionView/src/AnimatableVector3CompositionNode.cs b/labs/CompositionCollectionView/src/AnimatableVector3CompositionNode.cs new file mode 100644 index 000000000..5b360eb30 --- /dev/null +++ b/labs/CompositionCollectionView/src/AnimatableVector3CompositionNode.cs @@ -0,0 +1,64 @@ +#nullable enable +#if !WINAPPSDK +using System; +using System.Numerics; +using Windows.UI.Composition; +using static CommunityToolkit.Labs.WinUI.CompositionCollectionView.AnimationConstants; + +namespace CommunityToolkit.Labs.WinUI.CompositionCollectionView; +public class AnimatableVector3CompositionNode : IDisposable +{ + private Visual _underlyingVisual; + private bool disposedValue; + + public Vector3 Value { get => _underlyingVisual.Offset; set => _underlyingVisual.Offset = value; } + + + public AnimatableVector3CompositionNode(Compositor compositor) + { + _underlyingVisual = compositor.CreateShapeVisual(); + } + + public void Animate(CompositionAnimation animation) + { + _underlyingVisual.StartAnimation(Offset, animation); + } + + public void Animate(ExpressionNode animation) + { + _underlyingVisual.StartAnimation(Offset, animation); + } + + public Vector3Node Reference { get => _underlyingVisual.GetReference().Offset; } + + protected virtual void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + // TODO: dispose managed state (managed objects) + _underlyingVisual.Dispose(); + } + + // TODO: free unmanaged resources (unmanaged objects) and override finalizer + // TODO: set large fields to null + disposedValue = true; + } + } + + // // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources + // ~AnimatableScalarCompositionNode() + // { + // // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + // Dispose(disposing: false); + // } + + public void Dispose() + { + // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + Dispose(disposing: true); + GC.SuppressFinalize(this); + } +} +#endif diff --git a/labs/CompositionCollectionView/src/AnimationConstants.cs b/labs/CompositionCollectionView/src/AnimationConstants.cs new file mode 100644 index 000000000..2586ae144 --- /dev/null +++ b/labs/CompositionCollectionView/src/AnimationConstants.cs @@ -0,0 +1,57 @@ +#nullable enable +using System; +using System.Numerics; +using Windows.UI.Composition; + +namespace CommunityToolkit.Labs.WinUI.CompositionCollectionView; +public static class AnimationConstants +{ + // Strings for all the animatable properties of a composition visual + // as listed in https://docs.microsoft.com/en-us/uwp/api/windows.ui.composition.compositionobject.startanimation?view=winrt-19041 + public static Vector2PropertyName AnchorPoint { get; } = new Vector2PropertyName(nameof(AnchorPoint)); + public static Vector3PropertyName CenterPoint { get; } = new Vector3PropertyName(nameof(CenterPoint)); + public static Vector3PropertyName Offset { get; } = new Vector3PropertyName(nameof(Offset)); + public static Vector3PropertyName Translation { get; } = new Vector3PropertyName(nameof(Translation)); + public static Vector3PropertyName Scale { get; } = new Vector3PropertyName(nameof(Scale)); + public static string Opacity { get; } = nameof(Opacity); + public static Vector4PropertyName Orientation { get; } = new Vector4PropertyName(nameof(Orientation)); + public static string RotationAngle { get; } = nameof(RotationAngle); + public static Vector3PropertyName RotationAxis { get; } = new Vector3PropertyName(nameof(RotationAxis)); + public static Vector2PropertyName Size { get; } = new Vector2PropertyName(nameof(Size)); + public static string TransformMatrix { get; } = nameof(TransformMatrix); + + public class PropertyName + { + private readonly string _value; + public PropertyName(string value) + { + this._value = value; + } + public static implicit operator string(PropertyName PropertyName) => PropertyName._value; + public override string ToString() => _value; + } + + public class Vector2PropertyName : PropertyName + { + public Vector2PropertyName(string value) : base(value) + { + } + public string X => this + ".X"; + public string Y => this + ".Y"; + } + + public class Vector3PropertyName : Vector2PropertyName + { + public Vector3PropertyName(string value) : base(value) + { + } + public string Z => this + ".Z"; + } + public class Vector4PropertyName : Vector3PropertyName + { + public Vector4PropertyName(string value) : base(value) + { + } + public string W => this + ".W"; + } +} diff --git a/labs/CompositionCollectionView/src/Behaviors/ElementInteractionTrackerBehavior.cs b/labs/CompositionCollectionView/src/Behaviors/ElementInteractionTrackerBehavior.cs new file mode 100644 index 000000000..05290975e --- /dev/null +++ b/labs/CompositionCollectionView/src/Behaviors/ElementInteractionTrackerBehavior.cs @@ -0,0 +1,47 @@ +#nullable enable +using System.Collections.Generic; + +namespace CommunityToolkit.Labs.WinUI.CompositionCollectionView; +public class ElementInteractionTrackerBehavior : LayoutBehavior +{ + Dictionary> _elementTrackers = new(); + + public InteractionTrackerBehavior CreateTrackerFor(ElementReference element) + { + if (TryGetTrackerFor(element.Id, out var tracker) && tracker is not null) + { + return tracker; + } + + tracker = new InteractionTrackerBehavior(element.Container); + tracker.Configure(Layout); + _elementTrackers[element.Id] = tracker; + return tracker; + } + + public bool TryGetTrackerFor(TId id, out InteractionTrackerBehavior? tracker) + { + return _elementTrackers.TryGetValue(id, out tracker); + } + + //override public void CleanupElement(ElementReference element) + //{ + // _elementTrackers.Remove(element.Id); + //} + + override public void OnActivated() + { + foreach (var tracker in _elementTrackers) + { + tracker.Value.OnActivated(); + } + } + + override public void OnDeactivated() + { + foreach (var tracker in _elementTrackers) + { + tracker.Value.OnDeactivated(); + } + } +} diff --git a/labs/CompositionCollectionView/src/Behaviors/InteractionTrackerBehavior.cs b/labs/CompositionCollectionView/src/Behaviors/InteractionTrackerBehavior.cs new file mode 100644 index 000000000..1b7f6a8e7 --- /dev/null +++ b/labs/CompositionCollectionView/src/Behaviors/InteractionTrackerBehavior.cs @@ -0,0 +1,195 @@ +#nullable enable +using System; +using System.Collections.Generic; +using System.Numerics; +using System.Text; +using Windows.UI.Composition; +using Windows.UI.Composition.Interactions; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Hosting; + +namespace CommunityToolkit.Labs.WinUI.CompositionCollectionView; + public class InteractionTrackerBehavior : LayoutBehavior + { + public VisualInteractionSource InteractionSource { get; init; } + public InteractionTracker Tracker { get; init; } + public InteractionTrackerOwner TrackerOwner { get; init; } + + public bool IsUserInteracting { get; private set; } = false; + + + private List> _gestures = new List>(); + + public InteractionTrackerBehavior(FrameworkElement root) + { + var rootVisual = ElementCompositionPreview.GetElementVisual(root); + + InteractionSource = InitializeInteractionSource(); + TrackerOwner = new InteractionTrackerOwner(); + Tracker = InitializeTracker(); + + VisualInteractionSource InitializeInteractionSource() + { + var interactionSource = VisualInteractionSource.Create(rootVisual); + interactionSource.ScaleSourceMode = InteractionSourceMode.EnabledWithInertia; + interactionSource.PositionXSourceMode = InteractionSourceMode.EnabledWithInertia; + interactionSource.PositionYSourceMode = InteractionSourceMode.EnabledWithInertia; + interactionSource.IsPositionXRailsEnabled = false; + interactionSource.IsPositionYRailsEnabled = false; + interactionSource.ManipulationRedirectionMode = VisualInteractionSourceRedirectionMode.CapableTouchpadAndPointerWheel; + return interactionSource; + } + + InteractionTracker InitializeTracker() + { + var tracker = InteractionTracker.CreateWithOwner(rootVisual.Compositor, TrackerOwner); + tracker.InteractionSources.Add(InteractionSource); + return tracker; + } + } + + public virtual void AddGesture(InteractionTrackerGesture gesture) + { + if (gesture.PreviewControl is { }) + { + gesture.PreviewControl.HorizontalAlignment = Windows.UI.Xaml.HorizontalAlignment.Left; + gesture.PreviewControl.VerticalAlignment = VerticalAlignment.Top; + Layout.RootPanel.Children.Add(gesture.PreviewControl); + gesture.Restart(); + } + + if (Layout.IsActive) + { + RegisterGestureHandlers(gesture); + } + + _gestures.Add(gesture); + } + + public void RemoveGesture(InteractionTrackerGesture gesture) + { + gesture.Disable(); + UnregisterGestureHandlers(gesture); + + if (gesture.PreviewControl is { }) + { + Layout.RootPanel.Children.Remove(gesture.PreviewControl); + } + + _gestures.Remove(gesture); + if (gesture is IDisposable disposableGesture) + { + disposableGesture.Dispose(); + } + } + + private void RegisterGestureHandlers(InteractionTrackerGesture gesture) + { + TrackerOwner.OnInteractingStateEntered += gesture.InteractingStateEntered; + TrackerOwner.OnInertiaStateEntered += gesture.InertiaStateEntered; + TrackerOwner.OnValuesChanged += gesture.ValuesChanged; + } + + private void UnregisterGestureHandlers(InteractionTrackerGesture gesture) + { + TrackerOwner.OnInteractingStateEntered -= gesture.InteractingStateEntered; + TrackerOwner.OnInertiaStateEntered -= gesture.InertiaStateEntered; + TrackerOwner.OnValuesChanged -= gesture.ValuesChanged; + } + + public virtual void RestartGestures() + { + foreach (var gesture in _gestures) + { + gesture.Restart(); + } + } + + internal void Disable() + { + InteractionSource.IsPositionXRailsEnabled = false; + InteractionSource.IsPositionYRailsEnabled = false; + + InteractionSource.PositionXSourceMode = InteractionSourceMode.EnabledWithInertia; + InteractionSource.PositionYSourceMode = InteractionSourceMode.EnabledWithInertia; + Tracker.MaxPosition = new Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity); + Tracker.MinPosition = new Vector3(float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity); + } + + override public void OnActivated() + { + TrackerOwner.OnInertiaStateEntered += InertiaStateEntered; + TrackerOwner.OnInteractingStateEntered += InteractingStateEntered; + + foreach (var gesture in _gestures) + { + RegisterGestureHandlers(gesture); + } + } + + override public void OnDeactivated() + { + TrackerOwner.OnInertiaStateEntered -= InertiaStateEntered; + TrackerOwner.OnInteractingStateEntered -= InteractingStateEntered; + + for (var i = _gestures.Count - 1; i >= 0; i--) + { + RemoveGesture(_gestures[i]); + } + } + + private void InteractingStateEntered(InteractionTracker _, InteractionTrackerInteractingStateEnteredArgs _2) + { + IsUserInteracting = true; + } + + private void InertiaStateEntered(InteractionTracker sender, InteractionTrackerInertiaStateEnteredArgs args) + { + IsUserInteracting = false; + } + + public class InteractionTrackerOwner : IInteractionTrackerOwner + { + public delegate void CustomAnimationStateEnteredHandler(InteractionTracker sender, InteractionTrackerCustomAnimationStateEnteredArgs args); + public event CustomAnimationStateEnteredHandler? OnCustomAnimationStateEntered; + + public delegate void IdleStateEnteredHandler(InteractionTracker sender, InteractionTrackerIdleStateEnteredArgs args); + public event IdleStateEnteredHandler? OnIdleStateEntered; + + public delegate void InertiaStateEnteredHandler(InteractionTracker sender, InteractionTrackerInertiaStateEnteredArgs args); + public event InertiaStateEnteredHandler? OnInertiaStateEntered; + + public delegate void InteractingStateEnteredHandler(InteractionTracker sender, InteractionTrackerInteractingStateEnteredArgs args); + public event InteractingStateEnteredHandler? OnInteractingStateEntered; + + public delegate void RequestIgnoredHandler(InteractionTracker sender, InteractionTrackerRequestIgnoredArgs args); + public event RequestIgnoredHandler? OnRequestIgnored; + + public delegate void ValuesChangedHandler(InteractionTracker sender, InteractionTrackerValuesChangedArgs args); + public event ValuesChangedHandler? OnValuesChanged; + + public void CustomAnimationStateEntered(InteractionTracker sender, InteractionTrackerCustomAnimationStateEnteredArgs args) => OnCustomAnimationStateEntered?.Invoke(sender, args); + + public void IdleStateEntered(InteractionTracker sender, InteractionTrackerIdleStateEnteredArgs args) => OnIdleStateEntered?.Invoke(sender, args); + + public void InertiaStateEntered(InteractionTracker sender, InteractionTrackerInertiaStateEnteredArgs args) => OnInertiaStateEntered?.Invoke(sender, args); + + public void InteractingStateEntered(InteractionTracker sender, InteractionTrackerInteractingStateEnteredArgs args) => OnInteractingStateEntered?.Invoke(sender, args); + + public void RequestIgnored(InteractionTracker sender, InteractionTrackerRequestIgnoredArgs args) => OnRequestIgnored?.Invoke(sender, args); + + public void ValuesChanged(InteractionTracker sender, InteractionTrackerValuesChangedArgs args) => OnValuesChanged?.Invoke(sender, args); + + internal void Reset() + { + OnCustomAnimationStateEntered = null; + OnIdleStateEntered = null; + OnInertiaStateEntered = null; + OnInteractingStateEntered = null; + OnRequestIgnored = null; + OnValuesChanged = null; + } + } + } + diff --git a/labs/CompositionCollectionView/src/Behaviors/InteractionTrackerGesture/GesturePreviewControl.cs b/labs/CompositionCollectionView/src/Behaviors/InteractionTrackerGesture/GesturePreviewControl.cs new file mode 100644 index 000000000..fa43dab56 --- /dev/null +++ b/labs/CompositionCollectionView/src/Behaviors/InteractionTrackerGesture/GesturePreviewControl.cs @@ -0,0 +1,51 @@ +#nullable enable +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Hosting; +using Animation = CommunityToolkit.Labs.WinUI.CompositionCollectionView.AnimationConstants; + +namespace CommunityToolkit.Labs.WinUI.CompositionCollectionView; +public abstract class GesturePreviewControl : UserControl +{ + private ScalarNode? _opacity; + private Matrix4x4Node? _transform; + + public ScalarNode? OpacityNode + { + get => _opacity; + set + { + _opacity = value; + ResetVisualState(); + } + } + public Matrix4x4Node? TransformNode + { + get => _transform; + set + { + _transform = value; + ResetVisualState(); + } + } + + public virtual void ResetVisualState() + { + var visual = ElementCompositionPreview.GetElementVisual(this); + if (TransformNode is { }) + { + visual.StartAnimation(Animation.TransformMatrix, TransformNode); + } + if (OpacityNode is { }) + { + visual.StartAnimation(Animation.Opacity, OpacityNode); + } + } + + public abstract void SetPageSize(int width, int height); + public abstract Task StartCommandCompletedAnimation(float offset = 0); +} diff --git a/labs/CompositionCollectionView/src/Behaviors/InteractionTrackerGesture/InteractionTrackerGesture.cs b/labs/CompositionCollectionView/src/Behaviors/InteractionTrackerGesture/InteractionTrackerGesture.cs new file mode 100644 index 000000000..9a023bef7 --- /dev/null +++ b/labs/CompositionCollectionView/src/Behaviors/InteractionTrackerGesture/InteractionTrackerGesture.cs @@ -0,0 +1,146 @@ +#nullable enable +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Windows.UI.Composition; +using Windows.UI.Composition.Interactions; +using Windows.UI.Xaml.Hosting; +using static CommunityToolkit.Labs.WinUI.CompositionCollectionView.AnimationConstants; + + +namespace CommunityToolkit.Labs.WinUI.CompositionCollectionView; +public abstract class InteractionTrackerGesture +{ + public event EventHandler? GestureCompleted; + + protected BindableCompositionPropertySet LayoutProperties { get; init; } + protected CompositionPropertySet GestureProperties { get; init; } + + const string InteractionInProgressId = "IIP"; + protected bool InteractionInProgress + { + get => GestureProperties.TryGetBoolean(InteractionInProgressId, out var inProgress) == CompositionGetValueStatus.Succeeded && inProgress; + set => GestureProperties.InsertBoolean(InteractionInProgressId, value); + } + + protected BooleanNode InteractionInProgressReference => GestureProperties.GetReference().GetBooleanProperty(InteractionInProgressId); + + const string CompletionInProgressId = "CIP"; + + protected bool CompletionInProgress + { + get => GestureProperties.TryGetBoolean(CompletionInProgressId, out var inProgress) == CompositionGetValueStatus.Succeeded && inProgress; + set => GestureProperties.InsertBoolean(CompletionInProgressId, value); + } + + protected BooleanNode CompletionInProgressReference => GestureProperties.GetReference().GetBooleanProperty(CompletionInProgressId); + + const string InertiaInProgressId = "NIP"; + + protected bool InertiaInProgress + { + get => GestureProperties.TryGetBoolean(InertiaInProgressId, out var inProgress) == CompositionGetValueStatus.Succeeded && inProgress; + set => GestureProperties.InsertBoolean(InertiaInProgressId, value); + } + + protected BooleanNode InertiaInProgressReference => GestureProperties.GetReference().GetBooleanProperty(InertiaInProgressId); + + private InteractionTrackerReferenceNode _tracker; + + protected DateTime InteractionStartedTime { get; private set; } + + protected InteractionTrackerGesture(Compositor compositor, InteractionTrackerReferenceNode tracker, BindableCompositionPropertySet layoutProperties) + { + LayoutProperties = layoutProperties; + GestureProperties = compositor.CreatePropertySet(); + _tracker = tracker; + InteractionInProgress = false; + CompletionInProgress = false; + InertiaInProgress = false; + } + + private bool _isDisabled = false; + + //Disabling a gesture prevents it from processing tracker updates immediately, it can't be undone + public void Disable() => _isDisabled = true; + + internal void PauseAnimation() + { + var visual = ElementCompositionPreview.GetElementVisual(PreviewControl); + visual.StopAnimation(TransformMatrix); + visual.StopAnimation(Opacity); + } + + internal void Restart() + { + var visual = ElementCompositionPreview.GetElementVisual(PreviewControl); + + var visibility = GetPreviewVisibility(_tracker); + var opacity = GetPreviewOpacity(_tracker); + var transform = GetPreviewTransform(_tracker); + + visual.StartAnimation(TransformMatrix, transform); + visual.StartAnimation(Opacity, ExpressionFunctions.Conditional(visibility, + opacity, + 0)); + + PreviewControl?.ResetVisualState(); + InteractionInProgress = false; + CompletionInProgress = false; + } + + protected void InvokeGestureCompleted() + { + InteractionInProgress = false; + InertiaInProgress = false; + CompletionInProgress = true; + GestureCompleted?.Invoke(this, null); + } + public void ValuesChanged(InteractionTracker tracker, InteractionTrackerValuesChangedArgs args) + { + if (_isDisabled) + { + return; + } + OnValuesChanged(tracker, args); + } + + public void InteractingStateEntered(InteractionTracker _, InteractionTrackerInteractingStateEnteredArgs _1) + { + InteractionInProgress = true; + InertiaInProgress = false; + InteractionStartedTime = DateTime.Now; + } + + public void InertiaStateEntered(InteractionTracker tracker, InteractionTrackerInertiaStateEnteredArgs args) + { + if (_isDisabled) + { + return; + } + InteractionInProgress = false; + InertiaInProgress = true; + OnInertiaStateEntered(tracker, args); + } + + protected virtual void OnValuesChanged(InteractionTracker _, InteractionTrackerValuesChangedArgs _1) { } + + protected virtual void OnInertiaStateEntered(InteractionTracker _, InteractionTrackerInertiaStateEnteredArgs _1) { } + + protected abstract ScalarNode GetPreviewOpacity(InteractionTrackerReferenceNode tracker); + protected abstract BooleanNode GetPreviewVisibility(InteractionTrackerReferenceNode tracker); + protected abstract Matrix4x4Node GetPreviewTransform(InteractionTrackerReferenceNode tracker); + + public GesturePreviewControl? PreviewControl { get; set; } + +} + +public abstract class InteractionTrackerGesture : InteractionTrackerGesture where TPanningGesturePreview : GesturePreviewControl, new() +{ + protected InteractionTrackerGesture(Compositor compositor, InteractionTrackerReferenceNode tracker, BindableCompositionPropertySet layoutProperties) : base(compositor, tracker, layoutProperties) + { + PreviewControl = new TPanningGesturePreview(); + } +} diff --git a/labs/CompositionCollectionView/src/Behaviors/LayoutBehavior.cs b/labs/CompositionCollectionView/src/Behaviors/LayoutBehavior.cs new file mode 100644 index 000000000..b02b549da --- /dev/null +++ b/labs/CompositionCollectionView/src/Behaviors/LayoutBehavior.cs @@ -0,0 +1,26 @@ +#nullable enable + +using System; + +namespace CommunityToolkit.Labs.WinUI.CompositionCollectionView; +public abstract class LayoutBehavior +{ + protected Layout Layout => _layout is null ? throw new InvalidOperationException("Behavior has not been added to any layout yet") : _layout; + private Layout? _layout = null; + + public void Configure(Layout layout) + { + if (_layout != layout) + { + _layout = layout; + OnConfigure(); + } + } + + virtual public void ConfigureElement(ElementReference element) { } + virtual public void CleanupElement(ElementReference element) { } + + virtual public void OnConfigure() { } + virtual public void OnActivated() { } + virtual public void OnDeactivated() { } +} diff --git a/labs/CompositionCollectionView/src/BindableCompositionPropertySet.cs b/labs/CompositionCollectionView/src/BindableCompositionPropertySet.cs new file mode 100644 index 000000000..4fa95dd80 --- /dev/null +++ b/labs/CompositionCollectionView/src/BindableCompositionPropertySet.cs @@ -0,0 +1,123 @@ +#nullable enable +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Numerics; +using System.Text; +using Windows.UI; +using Windows.UI.Composition; + +namespace CommunityToolkit.Labs.WinUI.CompositionCollectionView; + +public class BindableCompositionPropertySet : INotifyPropertyChanged, IDisposable +{ + private CompositionPropertySet _propertySet; + private bool disposedValue; + + public event PropertyChangedEventHandler? PropertyChanged; + + public BindableCompositionPropertySet(CompositionPropertySet propertySet) + { + _propertySet = propertySet; + } + + public void InsertColor(string propertyName, Color value) + { + _propertySet.InsertColor(propertyName, value); + OnPropertyChanged(propertyName); + } + + public void InsertMatrix3x2(string propertyName, Matrix3x2 value) + { + _propertySet.InsertMatrix3x2(propertyName, value); + OnPropertyChanged(propertyName); + } + + public void InsertMatrix4x4(string propertyName, Matrix4x4 value) + { + _propertySet.InsertMatrix4x4(propertyName, value); + OnPropertyChanged(propertyName); + } + + public void InsertQuaternion(string propertyName, Quaternion value) + { + _propertySet.InsertQuaternion(propertyName, value); + OnPropertyChanged(propertyName); + } + + public void InsertScalar(string propertyName, float value) + { + _propertySet.InsertScalar(propertyName, value); + OnPropertyChanged(propertyName); + } + + public void InsertVector2(string propertyName, Vector2 value) + { + _propertySet.InsertVector2(propertyName, value); + OnPropertyChanged(propertyName); + } + + public void InsertVector3(string propertyName, Vector3 value) + { + _propertySet.InsertVector3(propertyName, value); + OnPropertyChanged(propertyName); + } + + public void InsertVector4(string propertyName, Vector4 value) + { + _propertySet.InsertVector4(propertyName, value); + OnPropertyChanged(propertyName); + } + + public void InsertBoolean(string propertyName, bool value) + { + _propertySet.InsertBoolean(propertyName, value); + OnPropertyChanged(propertyName); + } + + private void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + + public CompositionGetValueStatus TryGetColor(string propertyName, out Color value) => _propertySet.TryGetColor(propertyName, out value); + public CompositionGetValueStatus TryGetMatrix3x2(string propertyName, out Matrix3x2 value) => _propertySet.TryGetMatrix3x2(propertyName, out value); + public CompositionGetValueStatus TryGetMatrix4x4(string propertyName, out Matrix4x4 value) => _propertySet.TryGetMatrix4x4(propertyName, out value); + public CompositionGetValueStatus TryGetQuaternion(string propertyName, out Quaternion value) => _propertySet.TryGetQuaternion(propertyName, out value); + public CompositionGetValueStatus TryGetScalar(string propertyName, out float value) => _propertySet.TryGetScalar(propertyName, out value); + public CompositionGetValueStatus TryGetVector2(string propertyName, out Vector2 value) => _propertySet.TryGetVector2(propertyName, out value); + public CompositionGetValueStatus TryGetVector3(string propertyName, out Vector3 value) => _propertySet.TryGetVector3(propertyName, out value); + public CompositionGetValueStatus TryGetVector4(string propertyName, out Vector4 value) => _propertySet.TryGetVector4(propertyName, out value); + public CompositionGetValueStatus TryGetBoolean(string propertyName, out bool value) => _propertySet.TryGetBoolean(propertyName, out value); + + public PropertySetReferenceNode GetReference() => _propertySet.GetReference(); + + #region IDisposable + protected virtual void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + _propertySet.Dispose(); + } + + // TODO: free unmanaged resources (unmanaged objects) and override finalizer + // TODO: set large fields to null + disposedValue = true; + } + } + + // // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources + // ~BindableCompositionPropertySet() + // { + // // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + // Dispose(disposing: false); + // } + + public void Dispose() + { + // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + Dispose(disposing: true); + GC.SuppressFinalize(this); + } + #endregion +} + diff --git a/labs/CompositionCollectionView/src/CommunityToolkit.Labs.WinUI.CompositionCollectionView.csproj b/labs/CompositionCollectionView/src/CommunityToolkit.Labs.WinUI.CompositionCollectionView.csproj new file mode 100644 index 000000000..f8d1a4e87 --- /dev/null +++ b/labs/CompositionCollectionView/src/CommunityToolkit.Labs.WinUI.CompositionCollectionView.csproj @@ -0,0 +1,65 @@ + + + + + + + CommunityToolkit.Labs.WinUI.CompositionCollectionViewRns + + + + CommunityToolkit.Labs.$(PackageIdVariant).CompositionCollectionView + + This package contains CompositionCollectionView. + + 0.0.1 + warnings + True + + + + + + + + + + + + + + %(Filename) + + + + + + + + + + + + + + + + + + + MSBuild:Compile + + + MSBuild:Compile + + + MSBuild:Compile + + + MSBuild:Compile + + + MSBuild:Compile + + + diff --git a/labs/CompositionCollectionView/src/CompositionCollectionView.cs b/labs/CompositionCollectionView/src/CompositionCollectionView.cs new file mode 100644 index 000000000..bcfecafc9 --- /dev/null +++ b/labs/CompositionCollectionView/src/CompositionCollectionView.cs @@ -0,0 +1,80 @@ +#nullable enable +using System; +using System.Collections; +using System.Collections.Generic; +using Windows.UI.Composition; +using Windows.UI.Xaml.Controls; + +// The Templated Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234235 +namespace CommunityToolkit.Labs.WinUI.CompositionCollectionView; + + + public sealed class CompositionCollectionView : Control + { + private Canvas? _contentPanel; + private ILayout? _layout; + private Action? _pendingSourceUpdate; + public Layout? Layout() => _layout as Layout; + + public delegate void LayoutChangedHandler(CompositionCollectionView sender, ILayout newLayout); + public event LayoutChangedHandler? LayoutChanged; + + public CompositionCollectionView() + { + this.DefaultStyleKey = typeof(CompositionCollectionView); + } + + public void SetLayout(ILayout layout) + { + _layout = layout; + _layout.LayoutReplaced += OnLayoutReplaced; + + if (_contentPanel is not null) + { + _layout.Activate(_contentPanel); + } + } + + public void UpdateSource(IEnumerable<(TId id, Action> populateProperties)> source, Action? updateCallback = null) + { + .if (_contentPanel is not null) + { + (_layout as Layout)?.UpdateSource(source, updateCallback); + } + else + { + _pendingSourceUpdate = () => (_layout as Layout)?.UpdateSource(source); + updateCallback?.Invoke(); + } + } + + private void OnLayoutReplaced(ILayout sender, ILayout newLayout) + { + if (_layout is not null) + { + _layout.LayoutReplaced -= OnLayoutReplaced; + } + + _layout = newLayout; + _layout.LayoutReplaced += OnLayoutReplaced; + LayoutChanged?.Invoke(this, _layout); + } + + protected override void OnApplyTemplate() + { + if (GetTemplateChild("contentPanel") is Canvas contentPanel) + { + _contentPanel = contentPanel; + if (_layout is not null) + { + _layout.Activate(_contentPanel); + } + if(_pendingSourceUpdate is not null) + { + _pendingSourceUpdate?.Invoke(); + _pendingSourceUpdate = null; + } + } + } + } + diff --git a/labs/CompositionCollectionView/src/CompositionCollectionView.projitems b/labs/CompositionCollectionView/src/CompositionCollectionView.projitems new file mode 100644 index 000000000..f9bc626a7 --- /dev/null +++ b/labs/CompositionCollectionView/src/CompositionCollectionView.projitems @@ -0,0 +1,36 @@ + + + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) + true + bdb6d5d0-b5e2-4ade-9896-30cd295c2d7a + + + CompositionCollectionView + + + + + + + + + + + + + + + + + + + + Designer + MSBuild:Compile + + + + + + \ No newline at end of file diff --git a/labs/CompositionCollectionView/src/CompositionCollectionView.shproj b/labs/CompositionCollectionView/src/CompositionCollectionView.shproj new file mode 100644 index 000000000..38e94d974 --- /dev/null +++ b/labs/CompositionCollectionView/src/CompositionCollectionView.shproj @@ -0,0 +1,13 @@ + + + + bdb6d5d0-b5e2-4ade-9896-30cd295c2d7a + 14.0 + + + + + + + + diff --git a/labs/CompositionCollectionView/src/CompositionCollectionViewStyle_ClassicBinding.xaml b/labs/CompositionCollectionView/src/CompositionCollectionViewStyle_ClassicBinding.xaml new file mode 100644 index 000000000..053433573 --- /dev/null +++ b/labs/CompositionCollectionView/src/CompositionCollectionViewStyle_ClassicBinding.xaml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + 4,4,4,4 + + + + + + + + diff --git a/labs/CompositionCollectionView/src/CompositionCollectionViewStyle_xBind.xaml b/labs/CompositionCollectionView/src/CompositionCollectionViewStyle_xBind.xaml new file mode 100644 index 000000000..262dcce7e --- /dev/null +++ b/labs/CompositionCollectionView/src/CompositionCollectionViewStyle_xBind.xaml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + 4,4,4,4 + + + + + + + + diff --git a/labs/CompositionCollectionView/src/CompositionCollectionViewStyle_xBind.xaml.cs b/labs/CompositionCollectionView/src/CompositionCollectionViewStyle_xBind.xaml.cs new file mode 100644 index 000000000..e9d5914d5 --- /dev/null +++ b/labs/CompositionCollectionView/src/CompositionCollectionViewStyle_xBind.xaml.cs @@ -0,0 +1,20 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace CommunityToolkit.Labs.WinUI; + +/// +/// Backing code for this resource dictionary. +/// +public sealed partial class CompositionCollectionViewStyle_xBind : ResourceDictionary +{ + // NOTICE + // This file only exists to enable x:Bind in the resource dictionary. + // Do not add code here. + // Instead, add code-behind to your templated control. + public CompositionCollectionViewStyle_xBind() + { + this.InitializeComponent(); + } +} diff --git a/labs/CompositionCollectionView/src/CompositionCollectionView_ClassicBinding.cs b/labs/CompositionCollectionView/src/CompositionCollectionView_ClassicBinding.cs new file mode 100644 index 000000000..39cd7a82c --- /dev/null +++ b/labs/CompositionCollectionView/src/CompositionCollectionView_ClassicBinding.cs @@ -0,0 +1,95 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +#nullable enable + +namespace CommunityToolkit.Labs.WinUI; + +/// +/// An example templated control. +/// +[TemplatePart(Name = nameof(PART_HelloWorld), Type = typeof(TextBlock))] +public partial class CompositionCollectionView_ClassicBinding : Control +{ + /// + /// Creates a new instance of the class. + /// + public CompositionCollectionView_ClassicBinding() + { + this.DefaultStyleKey = typeof(CompositionCollectionView_ClassicBinding); + } + + /// + /// The primary text block that displays "Hello world". + /// + protected TextBlock? PART_HelloWorld { get; private set; } + + /// + protected override void OnApplyTemplate() + { + base.OnApplyTemplate(); + + // Detach all attached events when a new template is applied. + if (PART_HelloWorld is not null) + { + PART_HelloWorld.PointerEntered -= Element_PointerEntered; + } + + // Attach events when the template is applied and the control is loaded. + PART_HelloWorld = GetTemplateChild(nameof(PART_HelloWorld)) as TextBlock; + + if (PART_HelloWorld is not null) + { + PART_HelloWorld.PointerEntered += Element_PointerEntered; + } + } + + /// + /// The backing for the property. + /// + public static readonly DependencyProperty ItemPaddingProperty = DependencyProperty.Register( + nameof(ItemPadding), + typeof(Thickness), + typeof(CompositionCollectionView_ClassicBinding), + new PropertyMetadata(defaultValue: new Thickness(0))); + + /// + /// The backing for the property. + /// + public static readonly DependencyProperty MyPropertyProperty = DependencyProperty.Register( + nameof(MyProperty), + typeof(string), + typeof(CompositionCollectionView_ClassicBinding), + new PropertyMetadata(defaultValue: string.Empty, (d, e) => ((CompositionCollectionView_ClassicBinding)d).OnMyPropertyChanged((string)e.OldValue, (string)e.NewValue))); + + /// + /// Gets or sets an example string. A basic DependencyProperty example. + /// + public string MyProperty + { + get => (string)GetValue(MyPropertyProperty); + set => SetValue(MyPropertyProperty, value); + } + + /// + /// Gets or sets a padding for an item. A basic DependencyProperty example. + /// + public Thickness ItemPadding + { + get => (Thickness)GetValue(ItemPaddingProperty); + set => SetValue(ItemPaddingProperty, value); + } + + protected virtual void OnMyPropertyChanged(string oldValue, string newValue) + { + // Do something with the changed value. + } + + public void Element_PointerEntered(object sender, PointerRoutedEventArgs e) + { + if (sender is TextBlock text) + { + text.Opacity = 1; + } + } +} diff --git a/labs/CompositionCollectionView/src/CompositionCollectionView_xBind.cs b/labs/CompositionCollectionView/src/CompositionCollectionView_xBind.cs new file mode 100644 index 000000000..95bb7ee77 --- /dev/null +++ b/labs/CompositionCollectionView/src/CompositionCollectionView_xBind.cs @@ -0,0 +1,71 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace CommunityToolkit.Labs.WinUI; + +/// +/// An example templated control. +/// +public partial class CompositionCollectionView_xBind: Control +{ + /// + /// Creates a new instance of the class. + /// + public CompositionCollectionView_xBind() + { + this.DefaultStyleKey = typeof(CompositionCollectionView_xBind); + + // Allows directly using this control as the x:DataType in the template. + this.DataContext = this; + } + + /// + /// The backing for the property. + /// + public static readonly DependencyProperty ItemPaddingProperty = DependencyProperty.Register( + nameof(ItemPadding), + typeof(Thickness), + typeof(CompositionCollectionView_xBind), + new PropertyMetadata(defaultValue: new Thickness(0))); + + /// + /// The backing for the property. + /// + public static readonly DependencyProperty MyPropertyProperty = DependencyProperty.Register( + nameof(MyProperty), + typeof(string), + typeof(CompositionCollectionView_xBind), + new PropertyMetadata(defaultValue: string.Empty, (d, e) => ((CompositionCollectionView_xBind)d).OnMyPropertyChanged((string)e.OldValue, (string)e.NewValue))); + + /// + /// Gets or sets an example string. A basic DependencyProperty example. + /// + public string MyProperty + { + get => (string)GetValue(MyPropertyProperty); + set => SetValue(MyPropertyProperty, value); + } + + /// + /// Gets or sets a padding for an item. A basic DependencyProperty example. + /// + public Thickness ItemPadding + { + get => (Thickness)GetValue(ItemPaddingProperty); + set => SetValue(ItemPaddingProperty, value); + } + + protected virtual void OnMyPropertyChanged(string oldValue, string newValue) + { + // Do something with the changed value. + } + + public void Element_PointerEntered(object sender, PointerRoutedEventArgs e) + { + if (sender is TextBlock text) + { + text.Opacity = 1; + } + } +} diff --git a/labs/CompositionCollectionView/src/DeconstructPolyfillExtensions.cs b/labs/CompositionCollectionView/src/DeconstructPolyfillExtensions.cs new file mode 100644 index 000000000..b6bcdba76 --- /dev/null +++ b/labs/CompositionCollectionView/src/DeconstructPolyfillExtensions.cs @@ -0,0 +1,20 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Text; + +namespace CommunityToolkit.Labs.WinUI.CompositionCollectionView; +internal static class DeconstructPolyfillExtensions +{ + public static void Deconstruct( + this KeyValuePair pair, + out T1 key, + out T2 value) + { + key = pair.Key; + value = pair.Value; + } +} diff --git a/labs/CompositionCollectionView/src/Dependencies.WinUI2.props b/labs/CompositionCollectionView/src/Dependencies.WinUI2.props new file mode 100644 index 000000000..d69dec8ae --- /dev/null +++ b/labs/CompositionCollectionView/src/Dependencies.WinUI2.props @@ -0,0 +1,20 @@ + + + + + + + + + diff --git a/labs/CompositionCollectionView/src/Dependencies.WinUI3.props b/labs/CompositionCollectionView/src/Dependencies.WinUI3.props new file mode 100644 index 000000000..cb9f67653 --- /dev/null +++ b/labs/CompositionCollectionView/src/Dependencies.WinUI3.props @@ -0,0 +1,20 @@ + + + + + + + + + \ No newline at end of file diff --git a/labs/CompositionCollectionView/src/ElementReference.cs b/labs/CompositionCollectionView/src/ElementReference.cs new file mode 100644 index 000000000..d581a3941 --- /dev/null +++ b/labs/CompositionCollectionView/src/ElementReference.cs @@ -0,0 +1,77 @@ +#nullable enable +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Windows.UI.Composition; +using Windows.UI.Composition.Interactions; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Hosting; +using Windows.UI.Xaml.Input; + +namespace CommunityToolkit.Labs.WinUI.CompositionCollectionView; +public record ElementReference : IDisposable +{ + private bool disposedValue; + + public TId Id { get; init; } + public FrameworkElement Container { get; init; } + public Visual Visual { get; init; } + public Dictionary Properties { get; init; } + public CompositionPropertySet CompositionProperties { get; init; } + public AnimatableCompositionNodeSet AnimatableNodes { get; init; } + public Layout Layout { get; internal set; } + + public ElementReference(TId id, FrameworkElement container, Layout layout) + { + Id = id; + Container = container; + Visual = ElementCompositionPreview.GetElementVisual(Container); + Properties = new(); + CompositionProperties = Visual.Compositor.CreatePropertySet(); + AnimatableNodes = new AnimatableCompositionNodeSet(Visual.Compositor); + Layout = layout; + } + + internal void ReasignTo(Layout newLayout) + { + Layout = newLayout; + } + + public void SetZIndex(int zIndex) + { + //TODO: allow allow elements to process their own z index changes + Canvas.SetZIndex(Container, zIndex); + } + + protected virtual void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + // TODO: dispose managed state (managed objects) + CompositionProperties.Dispose(); + AnimatableNodes.Dispose(); + } + + // TODO: free unmanaged resources (unmanaged objects) and override finalizer + // TODO: set large fields to null + disposedValue = true; + } + } + + // // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources + // ~ElementReference() + // { + // // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + // Dispose(disposing: false); + // } + + public void Dispose() + { + // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + Dispose(disposing: true); + GC.SuppressFinalize(this); + } +} \ No newline at end of file diff --git a/labs/CompositionCollectionView/src/GlobalUsings_Local.cs b/labs/CompositionCollectionView/src/GlobalUsings_Local.cs new file mode 100644 index 000000000..7f5b050de --- /dev/null +++ b/labs/CompositionCollectionView/src/GlobalUsings_Local.cs @@ -0,0 +1,3 @@ +#if !WINAPPSDK +global using Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork; +#endif diff --git a/labs/CompositionCollectionView/src/IsExternalInit.cs b/labs/CompositionCollectionView/src/IsExternalInit.cs new file mode 100644 index 000000000..a9df15e0f --- /dev/null +++ b/labs/CompositionCollectionView/src/IsExternalInit.cs @@ -0,0 +1,13 @@ +using System.ComponentModel; + +namespace System.Runtime.CompilerServices +{ + /// + /// This class is required to make Record types work in .NET Framework and .NET Core 3.1. + /// It's included in .NET 5. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static class IsExternalInit + { + } +} diff --git a/labs/CompositionCollectionView/src/Layout.cs b/labs/CompositionCollectionView/src/Layout.cs new file mode 100644 index 000000000..d21251cfb --- /dev/null +++ b/labs/CompositionCollectionView/src/Layout.cs @@ -0,0 +1,547 @@ +#nullable enable +using System; +using System.Collections.Generic; +using System.Linq; +using System.Numerics; +using System.Threading.Tasks; +using Windows.UI.Composition; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Hosting; +using static CommunityToolkit.Labs.WinUI.CompositionCollectionView.AnimationConstants; + +namespace CommunityToolkit.Labs.WinUI.CompositionCollectionView; +public interface ILayout +{ + Action? LayoutReplaced { get; set; } + + void Activate(Panel panel); +} + +public abstract partial class Layout : ILayout, IDisposable +{ + public enum ElementAlignment { Start, Center, End }; + + public Layout(Func elementFactory, Action? log) + { + ElementFactory = elementFactory; + _log = log; + + var compositor = Window.Current.Compositor; + Properties = new BindableCompositionPropertySet(compositor.CreatePropertySet()); + AnimatableNodes = new AnimatableCompositionNodeSet(compositor); + } + + public Layout(Layout sourceLayout) + { + ParentLayout = sourceLayout; + + ElementFactory = sourceLayout.ElementFactory; + + _uiRoot = sourceLayout._uiRoot; + Properties = sourceLayout.Properties; + AnimatableNodes = sourceLayout.AnimatableNodes; + + HorizontalAlignment = sourceLayout.HorizontalAlignment; + + _log = sourceLayout._log; + } + + public void Activate(Panel panel) + { + var rootPanelVisual = InitializeRootContainer(panel); + + _uiRoot = new( + panel, + rootPanelVisual); + + Activate(); + + Visual InitializeRootContainer(Panel root) + { + var rootContainer = ElementCompositionPreview.GetElementVisual(root); + rootContainer.Size = new Vector2((float)root.ActualWidth, (float)root.ActualHeight); + return rootContainer; + } + } + + private void Activate() + { + //The parent layout should only be accessible before we transition to the current layout, + //once we activate the current layout we dispose and stop referencing it + ParentLayout?.Dispose(); + ParentLayout = null; + IsActive = true; + + RootPanel.SizeChanged += RootSizeChanged; + + foreach (var behavior in _behaviors) + { + behavior.Configure(this); + } + + OnActivated(); + + foreach (var behavior in _behaviors) + { + behavior.OnActivated(); + } + } + + private void Deactivate() + { + OnDeactivated(); + + IsActive = false; + + RootPanel.SizeChanged -= RootSizeChanged; + + foreach (var behavior in _behaviors) + { + behavior.OnDeactivated(); + } + } + + private void RootSizeChanged(object sender, SizeChangedEventArgs e) + { + OnElementsUpdated(); + } + + //Public properties + + public IEnumerable Source => Elements.Keys; + public Action? LayoutReplaced { get; set; } + + //Public methods + public T TransitionTo(Func, T> factory) where T : Layout + { + System.Diagnostics.Debug.Assert(IsActive); + + Deactivate(); + + var newLayout = factory(this); + newLayout.Activate(); + + TransferElements(); + + LayoutReplaced?.Invoke(this, newLayout); + + return newLayout; + + void TransferElements() + { + foreach (var (id, element) in Elements) + { + element.ReasignTo(newLayout); + newLayout.Elements.Add(id, element); + CleanupElement(element); + CleanupElementBehaviors(element); + } + + //Configure the animations after all the elements have been added to the new layout, + //to allow elements to depend on each other + foreach (var (id, element) in Elements) + { + newLayout.ConfigureElement(element); + newLayout.ConfigureElementBehaviors(element); + + var currentPosition = GetElementPositionValue(element); + var currentScale = GetElementScaleValue(element); + var currentOrientation = GetElementOrientationValue(element); + var currentOpacity = GetElementOpacityValue(element); + + var transition = newLayout.GetElementTransitionEasingFunction(element); + if (transition is not null) + { + TaskCompletionSource tsc = new(); + newLayout.StopElementAnimation(element); + + var progressAnimation = Compositor.CreateScalarKeyFrameAnimation(); + progressAnimation.Duration = TimeSpan.FromMilliseconds(transition.Length); + progressAnimation.StopBehavior = AnimationStopBehavior.SetToFinalValue; + progressAnimation.InsertKeyFrame(0, 0f, transition.EasingFunction); + progressAnimation.InsertKeyFrame(1, 1f, transition.EasingFunction); + + var animProgressNode = new AnimatableScalarCompositionNode(Compositor); + + element.Visual.StartAnimation(Offset, ExpressionFunctions.Lerp(currentPosition, newLayout.GetElementPositionNode(element), animProgressNode.Reference)); + var scale = newLayout.GetElementScaleNode(element); + element.Visual.StartAnimation(Scale, ExpressionFunctions.Lerp(new Vector3(currentScale), ExpressionFunctions.Vector3(scale, scale, scale), animProgressNode.Reference)); + element.Visual.StartAnimation(AnimationConstants.Orientation, ExpressionFunctions.Slerp(currentOrientation, newLayout.GetElementOrientationNode(element), animProgressNode.Reference)); + element.Visual.StartAnimation(Opacity, ExpressionFunctions.Lerp(currentOpacity, newLayout.GetElementOpacityNode(element), animProgressNode.Reference)); + + var batch = Compositor.CreateScopedBatch(CompositionBatchTypes.Animation); + batch.Completed += (object _, CompositionBatchCompletedEventArgs _1) => + { + if (newLayout.Elements.ContainsKey(element.Id)) + { + newLayout.ConfigureElementAnimation(element); + } + tsc.SetResult(true); + + batch.Dispose(); + animProgressNode.Dispose(); + progressAnimation.Dispose(); + }; + + animProgressNode.Animate(progressAnimation); + + batch.End(); + } + else + { + newLayout.ConfigureElementAnimation(element); + } + + newLayout.UpdateElement(element); + } + + Elements.Clear(); + + newLayout.OnElementsUpdated(); + } + } + + public ElementReference? GetElement(TId obId) => + Elements.TryGetValue(obId, out var element) ? element : null; + + //Protected properties + protected ScalarNode ViewportWidthNode => RootPanelVisual.GetReference().Size.X; + protected ScalarNode ViewportHeightNode => RootPanelVisual.GetReference().Size.Y; + + //Customizable behaviors + protected virtual void OnActivated() { } + protected virtual void OnDeactivated() { } + protected virtual void OnElementsUpdated() { } + + protected virtual void PopulateInitialElementPropertySet(CompositionPropertySet elementPropertySet, Dictionary elementProperties) { } + protected abstract void ConfigureElement(ElementReference element); + protected virtual void CleanupElement(ElementReference element) { } + public abstract Vector3Node GetElementPositionNode(ElementReference element); + public abstract ScalarNode GetElementScaleNode(ElementReference element); + + public virtual ScalarNode GetElementOpacityNode(ElementReference element) => 1; + public virtual QuaternionNode GetElementOrientationNode(ElementReference element) => Quaternion.Identity; + public abstract void UpdateElement(ElementReference element); + protected virtual Transition? GetElementTransitionEasingFunction(ElementReference element) => null; + + + //Internal implementation, the copy constructor should copy the properties we want to maintain across layouts + protected Func ElementFactory { get; init; } + + private record UIRoot(Panel RootPanel, Visual RootPanelVisual); + private UIRoot? _uiRoot; + + private UIRoot GetVisualProperties() + { + if (_uiRoot is null) + { + throw new InvalidOperationException("Tried to use this layout when it hasn't been activated yet."); + } + return _uiRoot; + } + + public Panel RootPanel => GetVisualProperties().RootPanel; + public Visual RootPanelVisual => GetVisualProperties().RootPanelVisual; + public Compositor Compositor => GetVisualProperties().RootPanelVisual.Compositor; + protected Dictionary> Elements { get; } = new Dictionary>(); + public BindableCompositionPropertySet Properties { private init; get; } + public AnimatableCompositionNodeSet AnimatableNodes { private init; get; } + //public bool IsUserInteractingWithTracker { get; private set; } = false; + + //internal Func? _shouldAcceptTouchInput; + internal Action? _log; + + + //private PointerEventHandler? _rootPointerPressedHandler; + //private PointerEventHandler? _rootPointerReleasedHandler; + //private PointerEventHandler? _rootPointerExitedHandler; + //private PointerEventHandler? _rootPointerCanceledHandler; + //private PointerEventHandler? _rootPointerCaptureLostHandler; + + + public Layout? ParentLayout { get; private set; } + + protected List> _behaviors = new List>(); + + //internal static Dictionary> ActiveTouchPointers { get; } = new(); + + public bool IsActive { get; private set; } = false; + + private bool disposedValue; + + private void ConfigureElementBehaviors(ElementReference elementReference) + { + foreach (var behavior in _behaviors) + { + behavior.ConfigureElement(elementReference); + } + } + + private void CleanupElementBehaviors(ElementReference elementReference) + { + foreach (var behavior in _behaviors) + { + behavior.CleanupElement(elementReference); + } + } + + public void ConfigureElementAnimation(ElementReference element, Visual? proxyVisual = null) + { + var visual = proxyVisual ?? element.Visual; + + visual.StartAnimation(Offset, GetElementPositionNode(element)); + + var scale = GetElementScaleNode(element); + visual.StartAnimation(Scale, ExpressionFunctions.Vector3(scale, scale, scale)); + + visual.StartAnimation(AnimationConstants.Orientation, GetElementOrientationNode(element)); + + visual.StartAnimation(Opacity, GetElementOpacityNode(element)); + } + + public void StopElementsAnimation() + { + foreach (var (_, element) in Elements) + { + StopElementAnimation(element); + } + } + + public void StopElementAnimation(ElementReference element) + { + element.Visual.StopAnimation(Offset); + element.Visual.StopAnimation(Scale); + element.Visual.StopAnimation(Opacity); + element.Visual.StopAnimation(AnimationConstants.Orientation); + } + + public IEnumerable> GetElements() => Elements.Values; + + bool _isUpdatingSource = false; + private record SourceUpdate(Dictionary>> UpdatedElements, Action? Callback); + Queue _pendingSourceUpdates = new(); + + public void UpdateSource(IEnumerable<(TId id, Action> populateProperties)> source, Action? updateCallback = null) + { + var updatedElements = source.ToDictionary(pair => pair.id, pair => pair.populateProperties); + if (!_isUpdatingSource) + { + _isUpdatingSource = true; + ProcessSourceUpdate(updatedElements, updateCallback); + } + else + { + _pendingSourceUpdates.Enqueue(new SourceUpdate(updatedElements, updateCallback)); + } + } + + public async void ProcessSourceUpdate(Dictionary>> updatedElements, Action? updateCallback) + { + List> elementUpdateTask = new(); + + System.Diagnostics.Debug.WriteLine("Process source update"); + + foreach (var (id, element) in Elements.ToArray()) + { + if (!updatedElements.ContainsKey(id)) + { + DestroyElement(element, id); + } + else + { + UpdateAndTransitionElement(element); + } + } + foreach (var (id, populateProperties) in updatedElements) + { + InstantiateElement(id, populateProperties); + } + + updateCallback?.Invoke(); + + await Task.WhenAll(elementUpdateTask); + + if (_pendingSourceUpdates.Count > 0) + { + var update = _pendingSourceUpdates.Dequeue(); + ProcessSourceUpdate(update.UpdatedElements, update.Callback); + } + else + { + _isUpdatingSource = false; + } + + OnElementsUpdated(); + + void InstantiateElement(TId id, Action> populateProperties) + { + var element = ElementFactory(id); + RootPanel.Children.Add(element); + + //var source = InitializeInteractionSource(); + + //var trackerOwner = new InteractionTrackerOwner(); + //trackerOwner.OnInertiaStateEntered += InertiaStateEntered; + + //var tracker = InteractionTracker.CreateWithOwner(source.Compositor, trackerOwner); + //tracker.InteractionSources.Add(source); + + var elementReference = new ElementReference(id, element,/* source, tracker, trackerOwner,*/ this); + PopulateInitialElementPropertySet(elementReference.CompositionProperties, elementReference.Properties); + populateProperties(elementReference.CompositionProperties, elementReference.Properties); + Elements[id] = elementReference; + + ConfigureElement(elementReference); + ConfigureElementBehaviors(elementReference); + + ConfigureElementAnimation(elementReference); + UpdateElement(elementReference); + + + //VisualInteractionSource InitializeInteractionSource() + //{ + // var interactionSource = VisualInteractionSource.Create(ElementCompositionPreview.GetElementVisual(element)); + // interactionSource.PositionXSourceMode = InteractionSourceMode.EnabledWithInertia; + // interactionSource.PositionYSourceMode = InteractionSourceMode.EnabledWithInertia; + // interactionSource.ManipulationRedirectionMode = VisualInteractionSourceRedirectionMode.CapableTouchpadAndPointerWheel; + // interactionSource.PositionXChainingMode = InteractionChainingMode.Always; + // interactionSource.PositionYChainingMode = InteractionChainingMode.Always; + // interactionSource.IsPositionXRailsEnabled = false; + // interactionSource.IsPositionYRailsEnabled = false; + // interactionSource.ScaleChainingMode = InteractionChainingMode.Always; + // return interactionSource; + //} + } + + void DestroyElement(ElementReference element, TId id) + { + RootPanel.Children.Remove(element.Container); + Elements.Remove(id); + element.Dispose(); + } + + void UpdateAndTransitionElement(ElementReference element) + { + var currentPosition = GetElementPositionValue(element); + var currentScale = GetElementScaleValue(element); + var currentOrientation = GetElementOrientationValue(element); + var currentOpacity = GetElementOpacityValue(element); + + + updatedElements[element.Id](element.CompositionProperties, element.Properties); + + var transition = GetElementTransitionEasingFunction(element); + if (transition is not null) + { + TaskCompletionSource tsc = new(); + StopElementAnimation(element); + + var progressAnimation = Compositor.CreateScalarKeyFrameAnimation(); + progressAnimation.Duration = TimeSpan.FromMilliseconds(transition.Length); + progressAnimation.StopBehavior = AnimationStopBehavior.SetToFinalValue; + progressAnimation.InsertKeyFrame(0, 0f, transition.EasingFunction); + progressAnimation.InsertKeyFrame(1, 1f, transition.EasingFunction); + + var animProgressNode = new AnimatableScalarCompositionNode(Compositor); + + element.Visual.StartAnimation(Offset, ExpressionFunctions.Lerp(currentPosition, GetElementPositionNode(element), animProgressNode.Reference)); + var scale = GetElementScaleNode(element); + element.Visual.StartAnimation(Scale, ExpressionFunctions.Lerp(new Vector3(currentScale), ExpressionFunctions.Vector3(scale, scale, scale), animProgressNode.Reference)); + element.Visual.StartAnimation(AnimationConstants.Orientation, ExpressionFunctions.Slerp(currentOrientation, GetElementOrientationNode(element), animProgressNode.Reference)); + element.Visual.StartAnimation(Opacity, ExpressionFunctions.Lerp(currentOpacity, GetElementOpacityNode(element), animProgressNode.Reference)); + + var batch = Compositor.CreateScopedBatch(CompositionBatchTypes.Animation); + batch.Completed += (object _, CompositionBatchCompletedEventArgs _1) => + { + if (IsActive) + { + ConfigureElementAnimation(element); + } + tsc.SetResult(true); + + batch.Dispose(); + animProgressNode.Dispose(); + progressAnimation.Dispose(); + }; + + animProgressNode.Animate(progressAnimation); + + batch.End(); + + elementUpdateTask.Add(tsc.Task); + } + + + UpdateElement(element); + updatedElements.Remove(element.Id); + } + } + + public record Transition(uint Length, CompositionEasingFunction EasingFunction); + + public virtual ElementAlignment HorizontalAlignment { get; set; } + + protected void AddBehavior(LayoutBehavior behavior) + { + if (IsActive) + { + behavior.Configure(this); + } + _behaviors.Add(behavior); + } + + public T GetBehavior() where T : LayoutBehavior => + _behaviors.OfType().First(); + + public T? TryGetBehavior() where T : LayoutBehavior => + _behaviors.OfType().FirstOrDefault(); + + protected void RemoveBehavior(LayoutBehavior behavior) + { + _behaviors.Remove(behavior); + } + + //todo add trackerPosition + public Vector3 GetElementPositionValue(ElementReference element, Vector3? trackerPosition = null) => GetElementPositionNode(element).Evaluate(); + public float GetElementScaleValue(ElementReference element) => GetElementScaleNode(element).Evaluate(); + public Quaternion GetElementOrientationValue(ElementReference element) => GetElementOrientationNode(element).Evaluate(); + public float GetElementOpacityValue(ElementReference element) => GetElementOpacityNode(element).Evaluate(); + + protected virtual void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + if (IsActive) + { + //We only want to dipose these fields if the layout is still active + //If it isn't, that means other layout owns them now + Properties.Dispose(); + //InteractionSource.Dispose(); + //Tracker.Dispose(); + AnimatableNodes.Dispose(); + } + } + + // TODO: free unmanaged resources (unmanaged objects) and override finalizer + // TODO: set large fields to null + disposedValue = true; + } + } + + // // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources + // ~Layout() + // { + // // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + // Dispose(disposing: false); + // } + + public void Dispose() + { + // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + Dispose(disposing: true); + GC.SuppressFinalize(this); + } +} diff --git a/labs/CompositionCollectionView/src/MathExtensions.cs b/labs/CompositionCollectionView/src/MathExtensions.cs new file mode 100644 index 000000000..9a50b70c7 --- /dev/null +++ b/labs/CompositionCollectionView/src/MathExtensions.cs @@ -0,0 +1,10 @@ +#nullable enable +using Windows.Foundation; + +namespace CompositionCollectionView +{ + internal static class MathExtensions + { + public static double DistanceTo(this Point p1, Point p2) => System.Math.Sqrt((p1.X - p2.X) * (p1.X - p2.X) + (p1.Y - p2.Y) * (p1.Y - p2.Y)); + } +} \ No newline at end of file diff --git a/labs/CompositionCollectionView/src/Themes/Generic.xaml b/labs/CompositionCollectionView/src/Themes/Generic.xaml new file mode 100644 index 000000000..481e3b1e0 --- /dev/null +++ b/labs/CompositionCollectionView/src/Themes/Generic.xaml @@ -0,0 +1,25 @@ + + + + + + + + + diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/CompositionCollectionView.Tests.projitems b/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/CompositionCollectionView.Tests.projitems new file mode 100644 index 000000000..f154cb20b --- /dev/null +++ b/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/CompositionCollectionView.Tests.projitems @@ -0,0 +1,14 @@ + + + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) + true + 69B7E819-DCF5-48F5-93DA-5191416A1270 + + + CompositionCollectionView.Tests + + + + + \ No newline at end of file diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/CompositionCollectionView.Tests.shproj b/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/CompositionCollectionView.Tests.shproj new file mode 100644 index 000000000..458b7a11e --- /dev/null +++ b/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/CompositionCollectionView.Tests.shproj @@ -0,0 +1,13 @@ + + + + 69B7E819-DCF5-48F5-93DA-5191416A1270 + 14.0 + + + + + + + + diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/ExampleCompositionCollectionViewTestClass.cs b/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/ExampleCompositionCollectionViewTestClass.cs new file mode 100644 index 000000000..ff5fff7b2 --- /dev/null +++ b/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/ExampleCompositionCollectionViewTestClass.cs @@ -0,0 +1,20 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace CompositionCollectionView.Tests; + +[TestClass] +public class ExampleCompositionCollectionViewTestClass +{ + // TODO: https://github.com/CommunityToolkit/Labs-Windows/issues/160 + [TestMethod] + public async Task SimpleExampleTest() + { + await CommunityToolkit.Labs.UnitTests.App.DispatcherQueue.EnqueueAsync(() => + { + var systemUnderTest = new CompositionCollectionView_ClassicBinding(); + Assert.IsNotNull(systemUnderTest); + }); + } +} diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.Uwp/CompositionCollectionView.UnitTests.Uwp.csproj b/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.Uwp/CompositionCollectionView.UnitTests.Uwp.csproj new file mode 100644 index 000000000..c1d8d8cce --- /dev/null +++ b/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.Uwp/CompositionCollectionView.UnitTests.Uwp.csproj @@ -0,0 +1,49 @@ + + + + + + + {87F8E99E-6C8A-43BA-9FAC-F8FE49347FC2} + CompositionCollectionView.UnitTests + CompositionCollectionView.UnitTests.Uwp + $(VisualStudioVersion) + + + + + + + + + + Designer + + + + + Assets\LockScreenLogo.scale-200.png + + + Assets\Square150x150Logo.scale-200.png + + + Assets\Square44x44Logo.scale-200.png + + + Assets\Square44x44Logo.targetsize-24_altform-unplated.png + + + Assets\StoreLogo.png + + + + + + + + + + + + diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.Uwp/Package.appxmanifest b/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.Uwp/Package.appxmanifest new file mode 100644 index 000000000..4da921f0f --- /dev/null +++ b/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.Uwp/Package.appxmanifest @@ -0,0 +1,45 @@ + + + + + + + + + CompositionCollectionView.UnitTests.Uwp + CommunityToolkit + Assets\StoreLogo.png + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.Uwp/Properties/AssemblyInfo.cs b/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.Uwp/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..3b5781f36 --- /dev/null +++ b/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.Uwp/Properties/AssemblyInfo.cs @@ -0,0 +1,22 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle("CompositionCollectionView.UnitTests.Uwp")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany(".NET Foundation")] +[assembly: AssemblyProduct("CompositionCollectionView.UnitTests.Uwp")] +[assembly: AssemblyCopyright("Copyright © .NET Foundation 2022")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +[assembly: AssemblyMetadata("TargetPlatform","UAP")] + +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: ComVisible(false)] \ No newline at end of file diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.Uwp/Properties/Default.rd.xml b/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.Uwp/Properties/Default.rd.xml new file mode 100644 index 000000000..996a8392a --- /dev/null +++ b/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.Uwp/Properties/Default.rd.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.WinAppSdk/CompositionCollectionView.UnitTests.WinAppSdk.csproj b/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.WinAppSdk/CompositionCollectionView.UnitTests.WinAppSdk.csproj new file mode 100644 index 000000000..9f4c1252d --- /dev/null +++ b/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.WinAppSdk/CompositionCollectionView.UnitTests.WinAppSdk.csproj @@ -0,0 +1,33 @@ + + + + CompositionCollectionView.UnitTests + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.WinAppSdk/Package.appxmanifest b/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.WinAppSdk/Package.appxmanifest new file mode 100644 index 000000000..8cb5970dd --- /dev/null +++ b/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.WinAppSdk/Package.appxmanifest @@ -0,0 +1,47 @@ + + + + + + + + CompositionCollectionView.UnitTests.WinAppSdk + CommunityToolkit + Assets\StoreLogo.png + + + + + + + + + + + + + + + + + + + + + + + diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.WinAppSdk/Properties/launchSettings.json b/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.WinAppSdk/Properties/launchSettings.json new file mode 100644 index 000000000..3aa65aa72 --- /dev/null +++ b/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.WinAppSdk/Properties/launchSettings.json @@ -0,0 +1,10 @@ +{ + "profiles": { + "CompositionCollectionView.UnitTests.WinAppSdk (Package)": { + "commandName": "MsixPackage" + }, + "CompositionCollectionView.UnitTests.WinAppSdk (Unpackaged)": { + "commandName": "Project" + } + } +} diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.WinAppSdk/app.manifest b/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.WinAppSdk/app.manifest new file mode 100644 index 000000000..84b8521ee --- /dev/null +++ b/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.WinAppSdk/app.manifest @@ -0,0 +1,15 @@ + + + + + + + + true/PM + PerMonitorV2, PerMonitor + + + From 8a959a9abdb3335bdb02eb77e21b2d5feb33ec7b Mon Sep 17 00:00:00 2001 From: Arcadio Garcia Salvadores Date: Fri, 8 Jul 2022 12:24:06 -0700 Subject: [PATCH 02/44] Samples --- .../ExpressionsFork/ExpressionsFork.csproj | 6 + .../ExpressionsFork/ExpressionsFork.nuspec | 36 ++++ .../CompositionCollectionView.Sample.csproj | 29 +++ ...positionCollectionViewFirstSamplePage.xaml | 28 ++- ...itionCollectionViewFirstSamplePage.xaml.cs | 102 ++++++----- .../InteractionTrackerSample.xaml | 10 ++ .../InteractionTrackerSample.xaml.cs | 166 ++++++++++++++++++ .../SwitchLayoutsSample.xaml | 13 ++ .../SwitchLayoutsSample.xaml.cs | 140 +++++++++++++++ .../src/AnimatableCompositionNodeSet.cs | 4 + .../src/AnimatableScalarCompositionNode.cs | 4 + .../src/AnimatableVector3CompositionNode.cs | 4 + .../src/AnimationConstants.cs | 4 + .../ElementInteractionTrackerBehavior.cs | 4 + .../Behaviors/InteractionTrackerBehavior.cs | 8 +- .../GesturePreviewControl.cs | 4 + .../InteractionTrackerGesture.cs | 8 +- .../src/Behaviors/LayoutBehavior.cs | 6 +- .../src/BindableCompositionPropertySet.cs | 4 + ...abs.WinUI.CompositionCollectionView.csproj | 65 +++++++ ...abs.WinUI.CompositionCollectionView.csproj | 2 +- .../src/CompositionCollectionView.cs | 6 +- .../src/ElementReference.cs | 8 +- .../src/GlobalUsings_Local.cs | 4 + .../src/IsExternalInit.cs | 4 + labs/CompositionCollectionView/src/Layout.cs | 4 + .../src/MathExtensions.cs | 10 -- 27 files changed, 595 insertions(+), 88 deletions(-) create mode 100644 labs/CompositionCollectionView/ExpressionsFork/ExpressionsFork.nuspec create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/InteractionTrackerSample.xaml create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/InteractionTrackerSample.xaml.cs create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/SwitchLayoutsSample.xaml create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/SwitchLayoutsSample.xaml.cs create mode 100644 labs/CompositionCollectionView/src/CommunityToolkit - Backup.Labs.WinUI.CompositionCollectionView.csproj delete mode 100644 labs/CompositionCollectionView/src/MathExtensions.cs diff --git a/labs/CompositionCollectionView/ExpressionsFork/ExpressionsFork.csproj b/labs/CompositionCollectionView/ExpressionsFork/ExpressionsFork.csproj index 95660eade..87e0e62b9 100644 --- a/labs/CompositionCollectionView/ExpressionsFork/ExpressionsFork.csproj +++ b/labs/CompositionCollectionView/ExpressionsFork/ExpressionsFork.csproj @@ -37,6 +37,7 @@ TRACE;NETFX_CORE;WINDOWS_UWP prompt 4 + true x86 @@ -57,6 +58,9 @@ pdbonly false prompt + true + + ARM @@ -97,6 +101,7 @@ pdbonly false prompt + true x64 @@ -119,6 +124,7 @@ pdbonly false prompt + true PackageReference diff --git a/labs/CompositionCollectionView/ExpressionsFork/ExpressionsFork.nuspec b/labs/CompositionCollectionView/ExpressionsFork/ExpressionsFork.nuspec new file mode 100644 index 000000000..c5ebfb5d8 --- /dev/null +++ b/labs/CompositionCollectionView/ExpressionsFork/ExpressionsFork.nuspec @@ -0,0 +1,36 @@ + + + + CommunityToolkit.ExpressionAnimations.Fork + 0.0.3 + CommunityToolkit.ExpressionAnimations.Fork + arcadiog + false + MIT + Private fork of the ExpressionAnimations feature from the CommunityToolkit + $copyright$ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/CompositionCollectionView.Sample.csproj b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/CompositionCollectionView.Sample.csproj index 36ad38b8f..a4cdac378 100644 --- a/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/CompositionCollectionView.Sample.csproj +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/CompositionCollectionView.Sample.csproj @@ -1,6 +1,9 @@ + + warnings + @@ -21,11 +24,37 @@ + + + + + + + + + + + + + SwitchLayoutsSample.xaml + + + SwitchLayoutsSample.xaml + + + + + Designer + + + Designer + + diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/CompositionCollectionViewFirstSamplePage.xaml b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/CompositionCollectionViewFirstSamplePage.xaml index 254a05237..01b8cf6c7 100644 --- a/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/CompositionCollectionViewFirstSamplePage.xaml +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/CompositionCollectionViewFirstSamplePage.xaml @@ -1,19 +1,13 @@ - - + mc:Ignorable="d"> + - Hello sdgsag - - - - + + + + diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/CompositionCollectionViewFirstSamplePage.xaml.cs b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/CompositionCollectionViewFirstSamplePage.xaml.cs index c5b6d823c..5d704e72b 100644 --- a/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/CompositionCollectionViewFirstSamplePage.xaml.cs +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/CompositionCollectionViewFirstSamplePage.xaml.cs @@ -1,74 +1,66 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using CommunityToolkit.Labs.Core.SourceGenerators; -using CommunityToolkit.Labs.Core.SourceGenerators.Attributes; +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +using CommunityToolkit.Labs.Core.SourceGenerators; +using CommunityToolkit.Labs.Core.SourceGenerators.Attributes; using CommunityToolkit.Labs.WinUI.CompositionCollectionView; using Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork; -#if !WINAPPSDK -using Windows.Foundation; -using Windows.Foundation.Collections; +#if !WINAPPSDK +using Windows.Foundation; +using Windows.Foundation.Collections; using Windows.UI.Composition; -using Windows.UI.Xaml; -using Windows.UI.Xaml.Controls; -using Windows.UI.Xaml.Controls.Primitives; -using Windows.UI.Xaml.Data; -using Windows.UI.Xaml.Input; -using Windows.UI.Xaml.Media; -using Windows.UI.Xaml.Navigation; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Controls.Primitives; +using Windows.UI.Xaml.Data; +using Windows.UI.Xaml.Input; +using Windows.UI.Xaml.Media; +using Windows.UI.Xaml.Navigation; using Windows.UI.Xaml.Shapes; -#else -using Microsoft.UI.Xaml; -using Microsoft.UI.Xaml.Controls; -using Microsoft.UI.Xaml.Controls.Primitives; -using Microsoft.UI.Xaml.Data; -using Microsoft.UI.Xaml.Input; -using Microsoft.UI.Xaml.Media; -using Microsoft.UI.Xaml.Navigation; -#endif +#else +using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Controls; +using Microsoft.UI.Xaml.Controls.Primitives; +using Microsoft.UI.Xaml.Data; +using Microsoft.UI.Xaml.Input; +using Microsoft.UI.Xaml.Media; +using Microsoft.UI.Xaml.Navigation; +#endif -namespace CompositionCollectionView.Sample -{ - [ToolkitSampleBoolOption("IsTextVisible", "IsVisible", true)] - // Single values without a colon are used for both label and value. - // To provide a different label for the value, separate with a colon surrounded by a single space on both sides ("label : value"). - [ToolkitSampleMultiChoiceOption("TextSize", title: "Text size", "Small : 12", "Normal : 16", "Big : 32")] - [ToolkitSampleMultiChoiceOption("TextFontFamily", title: "Font family", "Segoe UI", "Arial", "Consolas")] - [ToolkitSampleMultiChoiceOption("TextForeground", title: "Text foreground", - "Teal : #0ddc8c", - "Sand : #e7a676", - "Dull green : #5d7577")] +namespace CompositionCollectionView.Sample +{ + [ToolkitSample(id: nameof(CompositionCollectionViewFirstSamplePage), "Simple layout", description: "Displaying elements in a simple layout.")] + public sealed partial class CompositionCollectionViewFirstSamplePage : Page + { + private List<(uint, Action>)> elements { get; init; } = new() + { + (0, (_, _)=>{ }), + (1, (_, _)=>{ }), + (2, (_, _)=>{ }), + (3, (_, _)=>{ }) + }; - [ToolkitSample(id: nameof(CompositionCollectionViewFirstSamplePage), "Simple Options", description: "A sample page for showing how to do simple options.")] - public sealed partial class CompositionCollectionViewFirstSamplePage : Page - { - public CompositionCollectionViewFirstSamplePage() - { + public CompositionCollectionViewFirstSamplePage() + { this.InitializeComponent(); var layout = new SampleLayout((id) => - new Rectangle() { + new Rectangle() + { Width = 100, Height = 100, Fill = new SolidColorBrush(Windows.UI.Colors.BlueViolet) } , (_) => { }); compositionCollectionView.SetLayout(layout); - compositionCollectionView.UpdateSource(new List<(uint, Action>)>() - { - (0, (_,_)=>{ }), - (1, (_,_)=>{ }), - (2, (_,_)=>{ }), - (3, (_,_)=>{ }) - }); + compositionCollectionView.UpdateSource(elements); } public class SampleLayout : Layout { - public SampleLayout(Func elementFactory, Action? log) : base(elementFactory, log) + public SampleLayout(Func elementFactory, Action log) : base(elementFactory, log) { } @@ -87,5 +79,11 @@ public override void UpdateElement(ElementReference element) { } } - } -} + + private void Button_Click_Add(object sender, RoutedEventArgs e) + { + elements.Add(((uint)elements.Count, (_, _) => { })); + compositionCollectionView.UpdateSource(elements); + } + } +} diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/InteractionTrackerSample.xaml b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/InteractionTrackerSample.xaml new file mode 100644 index 000000000..058b262f5 --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/InteractionTrackerSample.xaml @@ -0,0 +1,10 @@ + + + diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/InteractionTrackerSample.xaml.cs b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/InteractionTrackerSample.xaml.cs new file mode 100644 index 000000000..2abcc31ce --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/InteractionTrackerSample.xaml.cs @@ -0,0 +1,166 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +using CommunityToolkit.Labs.Core.SourceGenerators; +using CommunityToolkit.Labs.Core.SourceGenerators.Attributes; +using CommunityToolkit.Labs.WinUI.CompositionCollectionView; +using Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork; +using System.Numerics; + +#if !WINAPPSDK +using Windows.Foundation; +using Windows.Foundation.Collections; +using Windows.UI; +using Windows.UI.Composition; +using Windows.UI.Composition.Interactions; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Controls.Primitives; +using Windows.UI.Xaml.Data; +using Windows.UI.Xaml.Hosting; +using Windows.UI.Xaml.Input; +using Windows.UI.Xaml.Media; +using Windows.UI.Xaml.Navigation; +using Windows.UI.Xaml.Shapes; +#else +using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Controls; +using Microsoft.UI.Xaml.Controls.Primitives; +using Microsoft.UI.Xaml.Data; +using Microsoft.UI.Xaml.Input; +using Microsoft.UI.Xaml.Media; +using Microsoft.UI.Xaml.Navigation; +#endif + + +namespace CompositionCollectionView.Sample +{ + [ToolkitSample(id: nameof(InteractionTrackerSample), "Interaction tracker layout", description: "Layout driven by an interaction tracker.")] + public sealed partial class InteractionTrackerSample : Page + { + const int ElementWidth = 100; + + private List<(uint, Action>)> elements { get; init; } = new() + { + (0, (_, _)=>{ }), + (1, (_, _)=>{ }), + (2, (_, _)=>{ }), + (3, (_, _)=>{ }), + (4, (_, _)=>{ }), + (5, (_, _)=>{ }) + }; + + public InteractionTrackerSample() + { + this.InitializeComponent(); + + var layout = new LinearLayout((id) => + new Rectangle() + { + Width = ElementWidth, + Height = ElementWidth, + Fill = new SolidColorBrush(Colors.BlueViolet), + Stroke = new SolidColorBrush(Colors.Gray), + StrokeThickness = 2 + } + , (_) => { }); + compositionCollectionView.SetLayout(layout); + compositionCollectionView.UpdateSource(elements); + } + + public class LinearLayout : Layout + { + public LinearLayout(Func elementFactory, Action log) : base(elementFactory, log) + { + } + + public LinearLayout(Layout sourceLayout) : base(sourceLayout) + { + } + + protected override void OnActivated() + { + if (TryGetBehavior>() is null) + { + // Tracker can't be created until activation, we don't have access to the root panel until then + var trackerBehavior = new InteractionTrackerBehavior(RootPanel); + AddBehavior(trackerBehavior); + + var tracker = trackerBehavior.Tracker; + var interactionSource = trackerBehavior.InteractionSource; + + UpdateTrackerLimits(); + + interactionSource.ScaleSourceMode = InteractionSourceMode.Disabled; + interactionSource.PositionXSourceMode = InteractionSourceMode.EnabledWithInertia; + interactionSource.PositionYSourceMode = InteractionSourceMode.Disabled; + } + + RootPanel.Background = new SolidColorBrush(Colors.Transparent); + RootPanel.PointerPressed += RootPointerPressed; + } + + protected override void OnDeactivated() + { + RootPanel.PointerPressed -= RootPointerPressed; + } + + void RootPointerPressed(object sender, PointerRoutedEventArgs e) + { + if (e.Pointer.PointerDeviceType == Windows.Devices.Input.PointerDeviceType.Touch) + { + var position = e.GetCurrentPoint(RootPanel); + GetBehavior>().InteractionSource.TryRedirectForManipulation(position); + } + } + + protected override void OnElementsUpdated() + { + UpdateTrackerLimits(); + } + + private void UpdateTrackerLimits() + { + var trackerBehavior = GetBehavior>(); + + var availableWidth = (float)RootPanel.ActualWidth - ElementWidth; + var elementsWidth = Elements.Count * ElementWidth * 1.2f; + + trackerBehavior.Tracker.MaxPosition = new Vector3(elementsWidth - ((float)RootPanel.ActualWidth + ElementWidth) / 2, 0, 0); + trackerBehavior.Tracker.MinPosition = new Vector3(-((float)RootPanel.ActualWidth - ElementWidth) / 2, 0, 0); + } + + private ScalarNode ScrollProgress(ElementReference element) + { + var availableWidth = RootPanelVisual.GetReference().Size.X - ElementWidth; + + return ExpressionFunctions.Clamp( + (element.Id * ElementWidth * 1.2f + - GetBehavior>().Tracker.GetReference().Position.X) / availableWidth, + 0, + 1); + } + + public override Vector3Node GetElementPositionNode(ElementReference element) + { + var availableWidth = RootPanelVisual.GetReference().Size.X - ElementWidth; + + var xPosition = availableWidth * ScrollProgress(element); + + var yPosition = 50 * ExpressionFunctions.Sin(ScrollProgress(element) * MathF.PI); + + return ExpressionFunctions.Vector3(xPosition, yPosition, 0); + } + + public override ScalarNode GetElementScaleNode(ElementReference element) => 1.5f - ExpressionFunctions.Abs(0.5f - ScrollProgress(element)); + + protected override void ConfigureElement(ElementReference element) + { + } + + public override void UpdateElement(ElementReference element) + { + } + } + } +} diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/SwitchLayoutsSample.xaml b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/SwitchLayoutsSample.xaml new file mode 100644 index 000000000..7bde8d30b --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/SwitchLayoutsSample.xaml @@ -0,0 +1,13 @@ + + + + + + + diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/SwitchLayoutsSample.xaml.cs b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/SwitchLayoutsSample.xaml.cs new file mode 100644 index 000000000..396641d6f --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/SwitchLayoutsSample.xaml.cs @@ -0,0 +1,140 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +using CommunityToolkit.Labs.Core.SourceGenerators; +using CommunityToolkit.Labs.Core.SourceGenerators.Attributes; +using CommunityToolkit.Labs.WinUI.CompositionCollectionView; +using Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork; +using System.Numerics; + +#if !WINAPPSDK +using Windows.Foundation; +using Windows.Foundation.Collections; +using Windows.UI.Composition; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Controls.Primitives; +using Windows.UI.Xaml.Data; +using Windows.UI.Xaml.Hosting; +using Windows.UI.Xaml.Input; +using Windows.UI.Xaml.Media; +using Windows.UI.Xaml.Navigation; +using Windows.UI.Xaml.Shapes; +#else +using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Controls; +using Microsoft.UI.Xaml.Controls.Primitives; +using Microsoft.UI.Xaml.Data; +using Microsoft.UI.Xaml.Input; +using Microsoft.UI.Xaml.Media; +using Microsoft.UI.Xaml.Navigation; +#endif + + +namespace CompositionCollectionView.Sample +{ + [ToolkitSample(id: nameof(SwitchLayoutsSample), "Layout transition", description: "Transition between different layouts.")] + public sealed partial class SwitchLayoutsSample : Page + { + private List<(uint, Action>)> elements { get; init; } = new() + { + (0, (_, _)=>{ }), + (1, (_, _)=>{ }), + (2, (_, _)=>{ }), + (3, (_, _)=>{ }), + (4, (_, _)=>{ }), + (5, (_, _)=>{ }) + }; + + public SwitchLayoutsSample() + { + this.InitializeComponent(); + + var layout = new LinearLayout((id) => + new Rectangle() + { + Width = 100, + Height = 100, + Fill = new SolidColorBrush(Windows.UI.Colors.BlueViolet) + } + , (_) => { }); + compositionCollectionView.SetLayout(layout); + compositionCollectionView.UpdateSource(elements); + } + + public class LinearLayout : Layout + { + public LinearLayout(Func elementFactory, Action log) : base(elementFactory, log) + { + } + + public LinearLayout(Layout sourceLayout) : base(sourceLayout) + { + } + + public override Vector3Node GetElementPositionNode(ElementReference element) + { + return ExpressionFunctions.Vector3(element.Id * 120, 0, 0); + } + + public override ScalarNode GetElementScaleNode(ElementReference element) => 1; + + protected override void ConfigureElement(ElementReference element) + { + } + + public override void UpdateElement(ElementReference element) + { + } + + protected override Transition GetElementTransitionEasingFunction(ElementReference element) => + new(100, + Window.Current.Compositor.CreateCubicBezierEasingFunction(new Vector2(0.25f, 0.1f), new Vector2(0.25f, 1f))); + } + + public class StackLayout : Layout + { + public StackLayout(Func elementFactory, Action log) : base(elementFactory, log) + { + } + + public StackLayout(Layout sourceLayout) : base(sourceLayout) + { + } + + public override Vector3Node GetElementPositionNode(ElementReference element) + { + return ExpressionFunctions.Vector3(element.Id * 10, element.Id * 10, 0); + } + + public override ScalarNode GetElementScaleNode(ElementReference element) => (float)Math.Pow(0.95f, element.Id); + + protected override void ConfigureElement(ElementReference element) + { + } + + public override void UpdateElement(ElementReference element) + { + } + + protected override Transition GetElementTransitionEasingFunction(ElementReference element) => + new(100, + Window.Current.Compositor.CreateCubicBezierEasingFunction(new Vector2(0.25f, 0.1f), new Vector2(0.25f, 1f))); + } + + private void ToggleSwitch_Toggled(object sender, RoutedEventArgs e) + { + if (sender is ToggleSwitch toggle) + { + if (toggle.IsOn && compositionCollectionView.Layout() is LinearLayout currentLinearLayout) + { + currentLinearLayout.TransitionTo(_ => new StackLayout(currentLinearLayout)); + } + else if (!toggle.IsOn && compositionCollectionView.Layout() is StackLayout currentStackLayout) + { + currentStackLayout.TransitionTo(_ => new LinearLayout(currentStackLayout)); + } + } + } + } +} diff --git a/labs/CompositionCollectionView/src/AnimatableCompositionNodeSet.cs b/labs/CompositionCollectionView/src/AnimatableCompositionNodeSet.cs index 4738dd1fa..aaeb93dec 100644 --- a/labs/CompositionCollectionView/src/AnimatableCompositionNodeSet.cs +++ b/labs/CompositionCollectionView/src/AnimatableCompositionNodeSet.cs @@ -1,3 +1,7 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + #nullable enable using System.Numerics; using Windows.UI.Composition; diff --git a/labs/CompositionCollectionView/src/AnimatableScalarCompositionNode.cs b/labs/CompositionCollectionView/src/AnimatableScalarCompositionNode.cs index 58a96a408..ae72ff0b7 100644 --- a/labs/CompositionCollectionView/src/AnimatableScalarCompositionNode.cs +++ b/labs/CompositionCollectionView/src/AnimatableScalarCompositionNode.cs @@ -1,3 +1,7 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + #nullable enable #if !WINAPPSDK using System.Numerics; diff --git a/labs/CompositionCollectionView/src/AnimatableVector3CompositionNode.cs b/labs/CompositionCollectionView/src/AnimatableVector3CompositionNode.cs index 5b360eb30..cd5336e1d 100644 --- a/labs/CompositionCollectionView/src/AnimatableVector3CompositionNode.cs +++ b/labs/CompositionCollectionView/src/AnimatableVector3CompositionNode.cs @@ -1,3 +1,7 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + #nullable enable #if !WINAPPSDK using System; diff --git a/labs/CompositionCollectionView/src/AnimationConstants.cs b/labs/CompositionCollectionView/src/AnimationConstants.cs index 2586ae144..7d70273fd 100644 --- a/labs/CompositionCollectionView/src/AnimationConstants.cs +++ b/labs/CompositionCollectionView/src/AnimationConstants.cs @@ -1,3 +1,7 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + #nullable enable using System; using System.Numerics; diff --git a/labs/CompositionCollectionView/src/Behaviors/ElementInteractionTrackerBehavior.cs b/labs/CompositionCollectionView/src/Behaviors/ElementInteractionTrackerBehavior.cs index 05290975e..b6e502808 100644 --- a/labs/CompositionCollectionView/src/Behaviors/ElementInteractionTrackerBehavior.cs +++ b/labs/CompositionCollectionView/src/Behaviors/ElementInteractionTrackerBehavior.cs @@ -1,3 +1,7 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + #nullable enable using System.Collections.Generic; diff --git a/labs/CompositionCollectionView/src/Behaviors/InteractionTrackerBehavior.cs b/labs/CompositionCollectionView/src/Behaviors/InteractionTrackerBehavior.cs index 1b7f6a8e7..fefea0072 100644 --- a/labs/CompositionCollectionView/src/Behaviors/InteractionTrackerBehavior.cs +++ b/labs/CompositionCollectionView/src/Behaviors/InteractionTrackerBehavior.cs @@ -1,3 +1,7 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + #nullable enable using System; using System.Collections.Generic; @@ -106,7 +110,7 @@ public virtual void RestartGestures() } } - internal void Disable() + public void Disable() { InteractionSource.IsPositionXRailsEnabled = false; InteractionSource.IsPositionYRailsEnabled = false; @@ -181,7 +185,7 @@ public class InteractionTrackerOwner : IInteractionTrackerOwner public void ValuesChanged(InteractionTracker sender, InteractionTrackerValuesChangedArgs args) => OnValuesChanged?.Invoke(sender, args); - internal void Reset() + public void Reset() { OnCustomAnimationStateEntered = null; OnIdleStateEntered = null; diff --git a/labs/CompositionCollectionView/src/Behaviors/InteractionTrackerGesture/GesturePreviewControl.cs b/labs/CompositionCollectionView/src/Behaviors/InteractionTrackerGesture/GesturePreviewControl.cs index fa43dab56..bcc19b5d4 100644 --- a/labs/CompositionCollectionView/src/Behaviors/InteractionTrackerGesture/GesturePreviewControl.cs +++ b/labs/CompositionCollectionView/src/Behaviors/InteractionTrackerGesture/GesturePreviewControl.cs @@ -1,3 +1,7 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + #nullable enable using System; using System.Collections.Generic; diff --git a/labs/CompositionCollectionView/src/Behaviors/InteractionTrackerGesture/InteractionTrackerGesture.cs b/labs/CompositionCollectionView/src/Behaviors/InteractionTrackerGesture/InteractionTrackerGesture.cs index 9a023bef7..d01c3b344 100644 --- a/labs/CompositionCollectionView/src/Behaviors/InteractionTrackerGesture/InteractionTrackerGesture.cs +++ b/labs/CompositionCollectionView/src/Behaviors/InteractionTrackerGesture/InteractionTrackerGesture.cs @@ -1,3 +1,7 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + #nullable enable using System; using System.Collections.Generic; @@ -66,14 +70,14 @@ protected InteractionTrackerGesture(Compositor compositor, InteractionTrackerRef //Disabling a gesture prevents it from processing tracker updates immediately, it can't be undone public void Disable() => _isDisabled = true; - internal void PauseAnimation() + public void PauseAnimation() { var visual = ElementCompositionPreview.GetElementVisual(PreviewControl); visual.StopAnimation(TransformMatrix); visual.StopAnimation(Opacity); } - internal void Restart() + public void Restart() { var visual = ElementCompositionPreview.GetElementVisual(PreviewControl); diff --git a/labs/CompositionCollectionView/src/Behaviors/LayoutBehavior.cs b/labs/CompositionCollectionView/src/Behaviors/LayoutBehavior.cs index b02b549da..3f97dd9bb 100644 --- a/labs/CompositionCollectionView/src/Behaviors/LayoutBehavior.cs +++ b/labs/CompositionCollectionView/src/Behaviors/LayoutBehavior.cs @@ -1,4 +1,8 @@ -#nullable enable +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#nullable enable using System; diff --git a/labs/CompositionCollectionView/src/BindableCompositionPropertySet.cs b/labs/CompositionCollectionView/src/BindableCompositionPropertySet.cs index 4fa95dd80..0aa99cf47 100644 --- a/labs/CompositionCollectionView/src/BindableCompositionPropertySet.cs +++ b/labs/CompositionCollectionView/src/BindableCompositionPropertySet.cs @@ -1,3 +1,7 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + #nullable enable using System; using System.Collections.Generic; diff --git a/labs/CompositionCollectionView/src/CommunityToolkit - Backup.Labs.WinUI.CompositionCollectionView.csproj b/labs/CompositionCollectionView/src/CommunityToolkit - Backup.Labs.WinUI.CompositionCollectionView.csproj new file mode 100644 index 000000000..a271ce127 --- /dev/null +++ b/labs/CompositionCollectionView/src/CommunityToolkit - Backup.Labs.WinUI.CompositionCollectionView.csproj @@ -0,0 +1,65 @@ + + + + + + + CommunityToolkit.Labs.WinUI.CompositionCollectionViewRns + + + + CommunityToolkit.Labs.$(PackageIdVariant).CompositionCollectionView + + This package contains CompositionCollectionView. + + 0.0.2 + warnings + True + + + + + + + + + + + + + + %(Filename) + + + + + + + + + + + + + + + + + + + MSBuild:Compile + + + MSBuild:Compile + + + MSBuild:Compile + + + MSBuild:Compile + + + MSBuild:Compile + + + diff --git a/labs/CompositionCollectionView/src/CommunityToolkit.Labs.WinUI.CompositionCollectionView.csproj b/labs/CompositionCollectionView/src/CommunityToolkit.Labs.WinUI.CompositionCollectionView.csproj index f8d1a4e87..443f26452 100644 --- a/labs/CompositionCollectionView/src/CommunityToolkit.Labs.WinUI.CompositionCollectionView.csproj +++ b/labs/CompositionCollectionView/src/CommunityToolkit.Labs.WinUI.CompositionCollectionView.csproj @@ -12,7 +12,7 @@ This package contains CompositionCollectionView. - 0.0.1 + 0.0.5 warnings True diff --git a/labs/CompositionCollectionView/src/CompositionCollectionView.cs b/labs/CompositionCollectionView/src/CompositionCollectionView.cs index bcfecafc9..df9f143cd 100644 --- a/labs/CompositionCollectionView/src/CompositionCollectionView.cs +++ b/labs/CompositionCollectionView/src/CompositionCollectionView.cs @@ -1,3 +1,7 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + #nullable enable using System; using System.Collections; @@ -37,7 +41,7 @@ public void SetLayout(ILayout layout) public void UpdateSource(IEnumerable<(TId id, Action> populateProperties)> source, Action? updateCallback = null) { - .if (_contentPanel is not null) + if (_contentPanel is not null) { (_layout as Layout)?.UpdateSource(source, updateCallback); } diff --git a/labs/CompositionCollectionView/src/ElementReference.cs b/labs/CompositionCollectionView/src/ElementReference.cs index d581a3941..a98fe86d8 100644 --- a/labs/CompositionCollectionView/src/ElementReference.cs +++ b/labs/CompositionCollectionView/src/ElementReference.cs @@ -1,4 +1,8 @@ -#nullable enable +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#nullable enable using System; using System.Collections.Generic; using System.Threading.Tasks; @@ -74,4 +78,4 @@ public void Dispose() Dispose(disposing: true); GC.SuppressFinalize(this); } -} \ No newline at end of file +} diff --git a/labs/CompositionCollectionView/src/GlobalUsings_Local.cs b/labs/CompositionCollectionView/src/GlobalUsings_Local.cs index 7f5b050de..2d4b636b0 100644 --- a/labs/CompositionCollectionView/src/GlobalUsings_Local.cs +++ b/labs/CompositionCollectionView/src/GlobalUsings_Local.cs @@ -1,3 +1,7 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + #if !WINAPPSDK global using Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork; #endif diff --git a/labs/CompositionCollectionView/src/IsExternalInit.cs b/labs/CompositionCollectionView/src/IsExternalInit.cs index a9df15e0f..076f9efe8 100644 --- a/labs/CompositionCollectionView/src/IsExternalInit.cs +++ b/labs/CompositionCollectionView/src/IsExternalInit.cs @@ -1,3 +1,7 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + using System.ComponentModel; namespace System.Runtime.CompilerServices diff --git a/labs/CompositionCollectionView/src/Layout.cs b/labs/CompositionCollectionView/src/Layout.cs index d21251cfb..94944683a 100644 --- a/labs/CompositionCollectionView/src/Layout.cs +++ b/labs/CompositionCollectionView/src/Layout.cs @@ -1,3 +1,7 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + #nullable enable using System; using System.Collections.Generic; diff --git a/labs/CompositionCollectionView/src/MathExtensions.cs b/labs/CompositionCollectionView/src/MathExtensions.cs deleted file mode 100644 index 9a50b70c7..000000000 --- a/labs/CompositionCollectionView/src/MathExtensions.cs +++ /dev/null @@ -1,10 +0,0 @@ -#nullable enable -using Windows.Foundation; - -namespace CompositionCollectionView -{ - internal static class MathExtensions - { - public static double DistanceTo(this Point p1, Point p2) => System.Math.Sqrt((p1.X - p2.X) * (p1.X - p2.X) + (p1.Y - p2.Y) * (p1.Y - p2.Y)); - } -} \ No newline at end of file From 7cfe44d5f87bbb4213af39d7e96fdf1fdba77bf6 Mon Sep 17 00:00:00 2001 From: Arcadio Garcia Salvadores Date: Mon, 5 Sep 2022 12:05:30 -0700 Subject: [PATCH 03/44] Maze WIP --- .../Expressions/ExpressionNodes/ScalarNode.cs | 4 +- .../ExpressionNodes/Vector4Node.cs | 7 +- .../ExpressionsFork/ExpressionsFork.nuspec | 2 +- .../Assets/ceiling.bmp | Bin 0 -> 778 bytes .../Assets/floor.bmp | Bin 0 -> 12344 bytes .../Assets/wall.bmp | Bin 0 -> 49208 bytes .../Assets/wall.png | Bin 0 -> 30238 bytes .../CompositionCollectionView.Sample.csproj | 10 + .../MazeSample.xaml | 11 + .../MazeSample.xaml.cs | 393 ++++++++++++++++++ .../src/AnimatableCompositionNodeSet.cs | 45 ++ .../src/AnimatableMatrix4x4CompositionNode.cs | 68 +++ .../AnimatableQuaternionCompositionNode.cs | 68 +++ labs/CompositionCollectionView/src/Layout.cs | 6 + 14 files changed, 610 insertions(+), 4 deletions(-) create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/Assets/ceiling.bmp create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/Assets/floor.bmp create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/Assets/wall.bmp create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/Assets/wall.png create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/MazeSample.xaml create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/MazeSample.xaml.cs create mode 100644 labs/CompositionCollectionView/src/AnimatableMatrix4x4CompositionNode.cs create mode 100644 labs/CompositionCollectionView/src/AnimatableQuaternionCompositionNode.cs diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/ScalarNode.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/ScalarNode.cs index 935930bef..5db1ef8d0 100644 --- a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/ScalarNode.cs +++ b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/ScalarNode.cs @@ -344,6 +344,8 @@ float GetProperty() return (Children[0] as BooleanNode).Evaluate() ? (Children[1] as ScalarNode).Evaluate() : (Children[2] as ScalarNode).Evaluate(); case ExpressionNodeType.Distance: return Vector2.Distance((Children[0] as Vector2Node).Evaluate(), (Children[1] as Vector2Node).Evaluate()); + case ExpressionNodeType.Clamp: + return Math.Clamp((Children[0] as ScalarNode).Evaluate(), (Children[1] as ScalarNode).Evaluate(), (Children[2] as ScalarNode).Evaluate()); case ExpressionNodeType.Lerp: { var start = (Children[0] as ScalarNode).Evaluate(); @@ -382,4 +384,4 @@ float GetProperty() } } #pragma warning restore CS0660, CS0661 -} \ No newline at end of file +} diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Vector4Node.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Vector4Node.cs index 0d0e7bca3..4f9189722 100644 --- a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Vector4Node.cs +++ b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Vector4Node.cs @@ -389,6 +389,9 @@ Vector4 GetProperty() case ExpressionNodeType.Negate: return -(Children[0] as Vector4Node).Evaluate(); + case ExpressionNodeType.Transform: + return + Vector4.Transform((Children[0] as Vector4Node).Evaluate(), (Children[1] as Matrix4x4Node).Evaluate()); case ExpressionNodeType.Multiply: return (Children[0], Children[1]) switch { @@ -401,7 +404,7 @@ Vector4 GetProperty() return (Children[0] as Vector4Node).Evaluate() / (Children[1] as Vector4Node).Evaluate(); - case ExpressionNodeType.Vector3: + case ExpressionNodeType.Vector4: return new Vector4( (Children[0] as ScalarNode).Evaluate(), (Children[1] as ScalarNode).Evaluate(), @@ -415,4 +418,4 @@ Vector4 GetProperty() } } #pragma warning restore CS0660, CS0661 -} \ No newline at end of file +} diff --git a/labs/CompositionCollectionView/ExpressionsFork/ExpressionsFork.nuspec b/labs/CompositionCollectionView/ExpressionsFork/ExpressionsFork.nuspec index c5ebfb5d8..4bf128073 100644 --- a/labs/CompositionCollectionView/ExpressionsFork/ExpressionsFork.nuspec +++ b/labs/CompositionCollectionView/ExpressionsFork/ExpressionsFork.nuspec @@ -2,7 +2,7 @@ CommunityToolkit.ExpressionAnimations.Fork - 0.0.3 + 0.0.4 CommunityToolkit.ExpressionAnimations.Fork arcadiog false diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/Assets/ceiling.bmp b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/Assets/ceiling.bmp new file mode 100644 index 0000000000000000000000000000000000000000..934b0ceb01caf6def182257ee0196f7c7e109769 GIT binary patch literal 778 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 S+LWK^JSe4~5|02MIPf3$gjE>; literal 0 HcmV?d00001 diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/Assets/wall.bmp b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/Assets/wall.bmp new file mode 100644 index 0000000000000000000000000000000000000000..491ddc9778fe83ef8cd48acac41caf464a8e31d9 GIT binary patch literal 49208 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 z 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 Ef{hDlRsaA1 literal 0 HcmV?d00001 diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/CompositionCollectionView.Sample.csproj b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/CompositionCollectionView.Sample.csproj index a4cdac378..d9ff1fc30 100644 --- a/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/CompositionCollectionView.Sample.csproj +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/CompositionCollectionView.Sample.csproj @@ -23,6 +23,10 @@ + + + + @@ -38,6 +42,12 @@ + + + + + + diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/MazeSample.xaml b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/MazeSample.xaml new file mode 100644 index 000000000..fbef18ec7 --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/MazeSample.xaml @@ -0,0 +1,11 @@ + + + diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/MazeSample.xaml.cs b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/MazeSample.xaml.cs new file mode 100644 index 000000000..9a21d3471 --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/MazeSample.xaml.cs @@ -0,0 +1,393 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +using CommunityToolkit.Labs.Core.SourceGenerators; +using CommunityToolkit.Labs.Core.SourceGenerators.Attributes; +using CommunityToolkit.Labs.WinUI.CompositionCollectionView; +using Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork; +using System.Numerics; + +#if !WINAPPSDK +using Windows.Foundation; +using Windows.Foundation.Collections; +using Windows.UI; +using Windows.UI.Composition; +using Windows.UI.Composition.Interactions; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Controls.Primitives; +using Windows.UI.Xaml.Data; +using Windows.UI.Xaml.Hosting; +using Windows.UI.Xaml.Input; +using Windows.UI.Xaml.Media; +using Windows.UI.Xaml.Media.Imaging; +using Windows.UI.Xaml.Navigation; +using Windows.UI.Xaml.Shapes; +#else +using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Controls; +using Microsoft.UI.Xaml.Controls.Primitives; +using Microsoft.UI.Xaml.Data; +using Microsoft.UI.Xaml.Input; +using Microsoft.UI.Xaml.Media; +using Microsoft.UI.Xaml.Navigation; +#endif + + +namespace CompositionCollectionView.Sample +{ + [ToolkitSample(id: nameof(MazeSample), "Maze layout", description: "Layout driven by an interaction tracker.")] + public sealed partial class MazeSample : Page + { + public const string X = nameof(X); + public const string Y = nameof(Y); + + enum TileType { Floor, Ceiling, HorizontalWall, VerticalWall } + + const int TileWidth = 100; + const int MazeSize = 10; + + static readonly Vector3 GoalPosition = new Vector3(900, -900, 0); + + private uint nextEntityId; + + private List<(uint, Action>)> elements { get; init; } = new(); + + public MazeSample() + { + this.InitializeComponent(); + + for (int i = 0; i < MazeSize; i++) + { + for (int j = 0; j < MazeSize; j++) + { + elements.Add(CreateElement(TileType.Floor, i, j)); + elements.Add(CreateElement(TileType.Ceiling, i, j)); + + if (j == 0) + { + elements.Add(CreateElement(TileType.HorizontalWall, i, j)); + } + else if (j == MazeSize - 1) + { + elements.Add(CreateElement(TileType.HorizontalWall, i, j + 1)); + } + + if (i == 0) + { + elements.Add(CreateElement(TileType.VerticalWall, i, j)); + } + else if (i == MazeSize - 1) + { + elements.Add(CreateElement(TileType.VerticalWall, i + 1, j)); + } + } + } + + var layout = new SpinningMazeLayout((id) => TileControl.Create(), (_) => { }); + compositionCollectionView.SetLayout(layout); + compositionCollectionView.UpdateSource(elements); + + Visual visual = ElementCompositionPreview.GetElementVisual(compositionCollectionView); + var viewSize = visual.GetReference().Size; + + visual.StartAnimation(AnimationConstants.TransformMatrix, + ExpressionFunctions.CreateTranslation(ExpressionFunctions.Vector3(-viewSize.X / 2, -viewSize.Y / 2, 0)) + * ExpressionFunctions.Matrix4x4( + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, -1.0f / viewSize.X, + 0.0f, 0.0f, 0.0f, 1.0f) * + ExpressionFunctions.CreateTranslation(ExpressionFunctions.Vector3(viewSize.X / 2, viewSize.Y / 2, 0))); + } + + private (uint, Action>) CreateElement(TileType type, int x, int y) + { + return (nextEntityId++, (_, dict) => + { + dict[nameof(TileType)] = type; + dict[X] = x; + dict[Y] = y; + } + ); + } + + public abstract class MazeLayout : Layout + { + protected const string PositionNode = nameof(PositionNode); + protected const string ScaleNode = nameof(ScaleNode); + protected const string RotationNode = nameof(RotationNode); + const string CameraTransformNode = nameof(CameraTransformNode); + + public MazeLayout(Func elementFactory, Action log) : base(elementFactory, log) + { + } + + public MazeLayout(Layout sourceLayout) : base(sourceLayout) + { + } + + protected override void OnActivated() + { + var translation = ExpressionFunctions.CreateTranslation(AnimatableNodes.GetOrCreateVector3Node(PositionNode, Vector3.Zero).Reference); + + var scaleNode = AnimatableNodes.GetOrCreateScalarNode(ScaleNode, 1).Reference; + var scale = ExpressionFunctions.CreateScale(ExpressionFunctions.Vector3(scaleNode, scaleNode, scaleNode)); + + var rotationNode = AnimatableNodes.GetOrCreateVector3Node(RotationNode, Vector3.Zero).Reference; + var rotation = ExpressionFunctions.CreateMatrix4x4FromAxisAngle(Vector3.UnitX, rotationNode.X) * + ExpressionFunctions.CreateMatrix4x4FromAxisAngle(Vector3.UnitY, rotationNode.Y) * + ExpressionFunctions.CreateMatrix4x4FromAxisAngle(Vector3.UnitZ, rotationNode.Z); + + AnimatableNodes.GetOrCreateMatrix4x4Node(CameraTransformNode, Matrix4x4.Identity).Animate(translation * rotation * scale); + + TileControl.LoadBrushes(); + } + + + public override Vector3Node GetElementPositionNode(ElementReference element) + { + element.Properties.TryGetValue(X, out var x); + element.Properties.TryGetValue(Y, out var y); + element.Properties.TryGetValue(nameof(TileType), out var tileType); + + var xPosition = tileType switch + { + _ => (int)x! * TileWidth + }; + + var yPosition = tileType switch + { + _ => (int)y! * TileWidth + }; + + var height = tileType switch + { + TileType.Floor => TileWidth, + TileType.Ceiling => 0, + _ => 0 + }; + + var camera = AnimatableNodes.GetOrCreateMatrix4x4Node(CameraTransformNode, Matrix4x4.Identity).Reference; + + return ExpressionFunctions.Transform(ExpressionFunctions.Vector4(xPosition, height, yPosition, 1), camera).XYZ; + } + + public override ScalarNode GetElementScaleNode(ElementReference element) + { + var camera = AnimatableNodes.GetOrCreateMatrix4x4Node(CameraTransformNode, Matrix4x4.Identity).Reference; + //return camera.Channel11; + + //return RootPanelVisual.GetReference().Size.Y / TileWidth; + + //return ExpressionFunctions.Transform(ExpressionFunctions.Vector4(1, 0, 0, 0), camera).X - + // ExpressionFunctions.Transform(ExpressionFunctions.Vector4(0, 0, 0, 0), camera).X; + + return AnimatableNodes.GetOrCreateScalarNode(ScaleNode, 1).Reference; + } + + public override QuaternionNode GetElementOrientationNode(ElementReference element) + { + var localOrientation = element.Properties[nameof(TileType)] switch + { + TileType.Floor => Quaternion.CreateFromYawPitchRoll(0, MathF.PI / 2, 0), + TileType.Ceiling => Quaternion.CreateFromYawPitchRoll(0, MathF.PI / 2, 0), + TileType.VerticalWall => Quaternion.CreateFromYawPitchRoll(-MathF.PI / 2, 0, 0), + TileType.HorizontalWall => Quaternion.Identity, + _ => Quaternion.Identity + }; + + var rotationNode = AnimatableNodes.GetOrCreateVector3Node(RotationNode, Vector3.Zero).Reference; + var cameraOrientation = ExpressionFunctions.CreateQuaternionFromAxisAngle(Vector3.UnitX, rotationNode.X) * + ExpressionFunctions.CreateQuaternionFromAxisAngle(Vector3.UnitY, rotationNode.Y) * + ExpressionFunctions.CreateQuaternionFromAxisAngle(Vector3.UnitZ, rotationNode.Z); + + return cameraOrientation * localOrientation; + } + + protected override void ConfigureElement(ElementReference element) + { + if (element.Container is Rectangle rect) + { + rect.Fill = TileControl.BrushFor((TileType)element.Properties[nameof(TileType)]!); + } + } + + public override void UpdateElement(ElementReference element) + { + } + + protected override Transition GetElementTransitionEasingFunction(ElementReference element) => + new(600, + Window.Current.Compositor.CreateCubicBezierEasingFunction(new Vector2(0.25f, 0.1f), new Vector2(0.25f, 1f))); + } + + public class SpinningMazeLayout : MazeLayout + { + public SpinningMazeLayout(Layout sourceLayout) : base(sourceLayout) + { + } + + public SpinningMazeLayout(Func elementFactory, Action log) : base(elementFactory, log) + { + } + + protected override void OnActivated() + { + base.OnActivated(); + + var animation = Compositor.CreateVector3KeyFrameAnimation(); + animation.Duration = TimeSpan.FromSeconds(5); + animation.InsertKeyFrame(0, Vector3.Zero); + animation.InsertKeyFrame(1, new Vector3(0, MathF.PI * 2, 0)); + animation.IterationBehavior = AnimationIterationBehavior.Forever; + + var rotationNode = AnimatableNodes.GetOrCreateVector3Node(RotationNode, Vector3.Zero); + rotationNode.Animate(animation); + + float mazeSide = TileWidth * MazeSize; + var mazeCenter = new Vector3(-mazeSide / 2, 0, -mazeSide / 2); + + AnimatableNodes.GetOrCreateVector3Node(PositionNode, Vector3.Zero).Animate(ExpressionFunctions.Vector3( + ExpressionFunctions.Sin(rotationNode.Reference.Y) * mazeSide * 1.5f, + mazeSide / 5, + -ExpressionFunctions.Cos(rotationNode.Reference.Y) * mazeSide * 1.5f + ) + (Vector3Node)mazeCenter); + + AnimatableNodes.GetOrCreateScalarNode(ScaleNode, 1).Animate(RootPanelVisual.GetReference().Size.Y / TileWidth); + RootPanel.Tapped += this.OnTapped; + } + + protected override void OnDeactivated() + { + RootPanel.Tapped -= OnTapped; + } + + private void OnTapped(object sender, TappedRoutedEventArgs e) + { + TransitionTo(x => new TraversableMazeLayout(this)); + } + } + + + public class TraversableMazeLayout : MazeLayout + { + public TraversableMazeLayout(Func elementFactory, Action log) : base(elementFactory, log) + { + } + + public TraversableMazeLayout(Layout sourceLayout) : base(sourceLayout) + { + } + + protected override void OnActivated() + { + base.OnActivated(); + + var trackerBehavior = TryGetBehavior>(); + + if (trackerBehavior is null) + { + // Tracker can't be created until activation, we don't have access to the root panel until then + trackerBehavior = new InteractionTrackerBehavior(RootPanel); + AddBehavior(trackerBehavior); + } + + var tracker = trackerBehavior.Tracker; + var interactionSource = trackerBehavior.InteractionSource; + + UpdateTrackerLimits(); + + interactionSource.ScaleSourceMode = InteractionSourceMode.Disabled; + interactionSource.PositionXSourceMode = InteractionSourceMode.EnabledWithInertia; + interactionSource.PositionYSourceMode = InteractionSourceMode.EnabledWithInertia; + + AnimatableNodes.GetOrCreateVector3Node(PositionNode, Vector3.Zero).Animate( + ExpressionFunctions.Vector3( + -tracker.GetReference().Position.X, + 0, + tracker.GetReference().Position.Y)); + + trackerBehavior.TrackerOwner.OnIdleStateEntered += this.OnTrackerIdleStateEntered; + + AnimatableNodes.GetOrCreateScalarNode(ScaleNode, 1).Animate(RootPanelVisual.GetReference().Size.Y / TileWidth); + AnimatableNodes.GetOrCreateVector3Node(RotationNode, Vector3.Zero).Value = new Vector3(0, 0, 0); + + RootPanel.Background = new SolidColorBrush(Colors.Black); + RootPanel.PointerPressed += RootPointerPressed; + } + + protected override void OnDeactivated() + { + RootPanel.PointerPressed -= RootPointerPressed; + GetBehavior>().TrackerOwner.OnIdleStateEntered -= this.OnTrackerIdleStateEntered; + } + + private void OnTrackerIdleStateEntered(InteractionTracker sender, InteractionTrackerIdleStateEnteredArgs args) + { + if (Vector3.Distance(sender.Position, GoalPosition) < TileWidth ) + { + TransitionTo(x => new SpinningMazeLayout(this)); + } + } + + void RootPointerPressed(object sender, PointerRoutedEventArgs e) + { + if (e.Pointer.PointerDeviceType == Windows.Devices.Input.PointerDeviceType.Touch) + { + var position = e.GetCurrentPoint(RootPanel); + GetBehavior>().InteractionSource.TryRedirectForManipulation(position); + } + } + + protected override void OnElementsUpdated() + { + UpdateTrackerLimits(); + } + + private void UpdateTrackerLimits() + { + var trackerBehavior = GetBehavior>(); + + trackerBehavior.Tracker.MaxPosition = new Vector3(TileWidth * (MazeSize - 1), 0, 0); + trackerBehavior.Tracker.MinPosition = new Vector3(0, -TileWidth * (MazeSize - 1), 0); + } + } + + private class TileControl + { + private static ImageBrush WallBrush, CeilingBrush, FloorBrush; + + public static Rectangle Create() => new Rectangle() + { + Width = TileWidth, + Height = TileWidth + }; + + public static void LoadBrushes() + { + WallBrush = WallBrush ?? new ImageBrush() + { + ImageSource = new BitmapImage(new Uri("ms-appx:///CompositionCollectionView.Sample/Assets/wall.bmp")) + }; + + CeilingBrush = CeilingBrush ?? new ImageBrush() + { + ImageSource = new BitmapImage(new Uri("ms-appx:///CompositionCollectionView.Sample/Assets/ceiling.bmp")) + }; + + FloorBrush = FloorBrush ?? new ImageBrush() + { + ImageSource = new BitmapImage(new Uri("ms-appx:///CompositionCollectionView.Sample/Assets/floor.bmp")) + }; + } + + public static ImageBrush BrushFor(TileType type) => type switch + { + TileType.Ceiling => CeilingBrush, + TileType.Floor => FloorBrush, + _ => WallBrush + }; + } + } +} diff --git a/labs/CompositionCollectionView/src/AnimatableCompositionNodeSet.cs b/labs/CompositionCollectionView/src/AnimatableCompositionNodeSet.cs index aaeb93dec..856b3fa20 100644 --- a/labs/CompositionCollectionView/src/AnimatableCompositionNodeSet.cs +++ b/labs/CompositionCollectionView/src/AnimatableCompositionNodeSet.cs @@ -63,6 +63,51 @@ public AnimatableVector3CompositionNode GetOrCreateVector3Node(string id, Vector } } + + public AnimatableQuaternionCompositionNode GetOrCreateQuaternionNode(string id, Quaternion defaultValue) + { + if (_nodes.ContainsKey(id)) + { + if (_nodes[id] is AnimatableQuaternionCompositionNode node) + { + return node; + } + else + { + throw new InvalidCastException("Node {id} is not a vector3 node"); + } + } + else + { + var newNode = new AnimatableQuaternionCompositionNode(_compositor); + newNode.Value = defaultValue; + _nodes[id] = newNode; + return newNode; + } + } + + public AnimatableMatrix4x4CompositionNode GetOrCreateMatrix4x4Node(string id, Matrix4x4 defaultValue) + { + if (_nodes.ContainsKey(id)) + { + if (_nodes[id] is AnimatableMatrix4x4CompositionNode node) + { + return node; + } + else + { + throw new InvalidCastException("Node {id} is not a matrix4x4 node"); + } + } + else + { + var newNode = new AnimatableMatrix4x4CompositionNode(_compositor); + newNode.Value = defaultValue; + _nodes[id] = newNode; + return newNode; + } + } + protected virtual void Dispose(bool disposing) { if (!disposedValue) diff --git a/labs/CompositionCollectionView/src/AnimatableMatrix4x4CompositionNode.cs b/labs/CompositionCollectionView/src/AnimatableMatrix4x4CompositionNode.cs new file mode 100644 index 000000000..72b4d0e1a --- /dev/null +++ b/labs/CompositionCollectionView/src/AnimatableMatrix4x4CompositionNode.cs @@ -0,0 +1,68 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#nullable enable +#if !WINAPPSDK +using System; +using System.Numerics; +using Windows.UI.Composition; +using static CommunityToolkit.Labs.WinUI.CompositionCollectionView.AnimationConstants; + +namespace CommunityToolkit.Labs.WinUI.CompositionCollectionView; +public class AnimatableMatrix4x4CompositionNode : IDisposable +{ + private Visual _underlyingVisual; + private bool disposedValue; + + public Matrix4x4 Value { get => _underlyingVisual.TransformMatrix; set => _underlyingVisual.TransformMatrix = value; } + + + public AnimatableMatrix4x4CompositionNode(Compositor compositor) + { + _underlyingVisual = compositor.CreateShapeVisual(); + } + + public void Animate(CompositionAnimation animation) + { + _underlyingVisual.StartAnimation(TransformMatrix, animation); + } + + public void Animate(ExpressionNode animation) + { + _underlyingVisual.StartAnimation(TransformMatrix, animation); + } + + public Matrix4x4Node Reference { get => _underlyingVisual.GetReference().TransformMatrix; } + + protected virtual void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + // TODO: dispose managed state (managed objects) + _underlyingVisual.Dispose(); + } + + // TODO: free unmanaged resources (unmanaged objects) and override finalizer + // TODO: set large fields to null + disposedValue = true; + } + } + + // // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources + // ~AnimatableScalarCompositionNode() + // { + // // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + // Dispose(disposing: false); + // } + + public void Dispose() + { + // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + Dispose(disposing: true); + GC.SuppressFinalize(this); + } +} +#endif diff --git a/labs/CompositionCollectionView/src/AnimatableQuaternionCompositionNode.cs b/labs/CompositionCollectionView/src/AnimatableQuaternionCompositionNode.cs new file mode 100644 index 000000000..d3b7d70bc --- /dev/null +++ b/labs/CompositionCollectionView/src/AnimatableQuaternionCompositionNode.cs @@ -0,0 +1,68 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#nullable enable +#if !WINAPPSDK +using System; +using System.Numerics; +using Windows.UI.Composition; +using static CommunityToolkit.Labs.WinUI.CompositionCollectionView.AnimationConstants; + +namespace CommunityToolkit.Labs.WinUI.CompositionCollectionView; +public class AnimatableQuaternionCompositionNode : IDisposable +{ + private Visual _underlyingVisual; + private bool disposedValue; + + public Quaternion Value { get => _underlyingVisual.Orientation; set => _underlyingVisual.Orientation = value; } + + + public AnimatableQuaternionCompositionNode(Compositor compositor) + { + _underlyingVisual = compositor.CreateShapeVisual(); + } + + public void Animate(CompositionAnimation animation) + { + _underlyingVisual.StartAnimation(AnimationConstants.Orientation, animation); + } + + public void Animate(ExpressionNode animation) + { + _underlyingVisual.StartAnimation(AnimationConstants.Orientation, animation); + } + + public QuaternionNode Reference { get => _underlyingVisual.GetReference().Orientation; } + + protected virtual void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + // TODO: dispose managed state (managed objects) + _underlyingVisual.Dispose(); + } + + // TODO: free unmanaged resources (unmanaged objects) and override finalizer + // TODO: set large fields to null + disposedValue = true; + } + } + + // // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources + // ~AnimatableScalarCompositionNode() + // { + // // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + // Dispose(disposing: false); + // } + + public void Dispose() + { + // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + Dispose(disposing: true); + GC.SuppressFinalize(this); + } +} +#endif diff --git a/labs/CompositionCollectionView/src/Layout.cs b/labs/CompositionCollectionView/src/Layout.cs index 94944683a..848b3f3d7 100644 --- a/labs/CompositionCollectionView/src/Layout.cs +++ b/labs/CompositionCollectionView/src/Layout.cs @@ -124,6 +124,12 @@ public T TransitionTo(Func, T> factory) where T : Layout Deactivate(); var newLayout = factory(this); + + foreach(var behavior in _behaviors) + { + newLayout.AddBehavior(behavior); + } + newLayout.Activate(); TransferElements(); From 61be6d3c8eae935e5cf306234a53958e4caa4de9 Mon Sep 17 00:00:00 2001 From: Arcadio Garcia Salvadores Date: Mon, 5 Sep 2022 14:05:19 -0700 Subject: [PATCH 04/44] CCV project --- .../CompositionCollectionView.sln | 311 ++++++++++++++++++ .../CompositionCollectionView.Samples.csproj | 23 ++ .../CompositionCollectionView.md | 64 ++++ ...CompositionCollectionViewCustomSample.xaml | 21 ++ ...positionCollectionViewCustomSample.xaml.cs | 27 ++ ...positionCollectionViewTemplatedSample.xaml | 16 + ...itionCollectionViewTemplatedSample.xaml.cs | 24 ++ ...lectionViewTemplatedStyleCustomSample.xaml | 26 ++ ...tionViewTemplatedStyleCustomSample.xaml.cs | 24 ++ ...sitionCollectionViewXbindBackedSample.xaml | 16 + ...ionCollectionViewXbindBackedSample.xaml.cs | 24 ++ ...ctionViewXbindBackedStyleCustomSample.xaml | 26 ++ ...onViewXbindBackedStyleCustomSample.xaml.cs | 24 ++ .../Dependencies.props | 31 ++ .../CompositionCollectionView.Uwp.csproj | 61 ++++ .../Package.appxmanifest | 49 +++ .../Properties/AssemblyInfo.cs | 33 ++ .../Properties/Default.rd.xml | 31 ++ .../CompositionCollectionView.Wasm.csproj | 41 +++ .../CompositionCollectionView.Wasm/Program.cs | 19 ++ .../Properties/launchSettings.json | 27 ++ .../WasmCSS/Fonts.css | 27 ++ .../WasmScripts/AppManifest.js | 5 + .../wwwroot/web.config | 78 +++++ ...CompositionCollectionView.WinAppSdk.csproj | 46 +++ .../Package.appxmanifest | 49 +++ .../Properties/launchSettings.json | 10 + .../app.manifest | 15 + .../src/AdditionalAssemblyInfo.cs | 13 + ...abs.WinUI.CompositionCollectionView.csproj | 25 ++ .../src/CompositionCollectionView.cs | 108 ++++++ ...ionCollectionViewStyle_ClassicBinding.xaml | 62 ++++ .../CompositionCollectionViewStyle_xBind.xaml | 69 ++++ ...mpositionCollectionViewStyle_xBind.xaml.cs | 20 ++ ...ompositionCollectionView_ClassicBinding.cs | 94 ++++++ .../src/CompositionCollectionView_xBind.cs | 71 ++++ .../src/Dependencies.props | 31 ++ .../src/Themes/Generic.xaml | 10 + ...CompositionCollectionView.Tests.Uwp.csproj | 61 ++++ .../Package.appxmanifest | 47 +++ .../Properties/AssemblyInfo.cs | 22 ++ .../Properties/Default.rd.xml | 29 ++ ...itionCollectionView.Tests.WinAppSdk.csproj | 43 +++ .../Package.appxmanifest | 48 +++ .../Properties/launchSettings.json | 10 + .../app.manifest | 15 + .../CompositionCollectionView.Tests.projitems | 23 ++ .../CompositionCollectionView.Tests.shproj | 13 + ...ampleCompositionCollectionViewTestClass.cs | 132 ++++++++ ...mpleCompositionCollectionViewTestPage.xaml | 14 + ...eCompositionCollectionViewTestPage.xaml.cs | 16 + 51 files changed, 2124 insertions(+) create mode 100644 labs/CompositionCollectionView/CompositionCollectionView.sln create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionView.Samples.csproj create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionView.md create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewCustomSample.xaml create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewCustomSample.xaml.cs create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewTemplatedSample.xaml create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewTemplatedSample.xaml.cs create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewTemplatedStyleCustomSample.xaml create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewTemplatedStyleCustomSample.xaml.cs create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewXbindBackedSample.xaml create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewXbindBackedSample.xaml.cs create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewXbindBackedStyleCustomSample.xaml create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewXbindBackedStyleCustomSample.xaml.cs create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/Dependencies.props create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Uwp/CompositionCollectionView.Uwp.csproj create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Uwp/Package.appxmanifest create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Uwp/Properties/AssemblyInfo.cs create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Uwp/Properties/Default.rd.xml create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/CompositionCollectionView.Wasm.csproj create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/Program.cs create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/Properties/launchSettings.json create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/WasmCSS/Fonts.css create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/WasmScripts/AppManifest.js create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/wwwroot/web.config create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.WinAppSdk/CompositionCollectionView.WinAppSdk.csproj create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.WinAppSdk/Package.appxmanifest create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.WinAppSdk/Properties/launchSettings.json create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.WinAppSdk/app.manifest create mode 100644 labs/CompositionCollectionView/src/AdditionalAssemblyInfo.cs create mode 100644 labs/CompositionCollectionView/src/CommunityToolkit.Labs.WinUI.CompositionCollectionView.csproj create mode 100644 labs/CompositionCollectionView/src/CompositionCollectionView.cs create mode 100644 labs/CompositionCollectionView/src/CompositionCollectionViewStyle_ClassicBinding.xaml create mode 100644 labs/CompositionCollectionView/src/CompositionCollectionViewStyle_xBind.xaml create mode 100644 labs/CompositionCollectionView/src/CompositionCollectionViewStyle_xBind.xaml.cs create mode 100644 labs/CompositionCollectionView/src/CompositionCollectionView_ClassicBinding.cs create mode 100644 labs/CompositionCollectionView/src/CompositionCollectionView_xBind.cs create mode 100644 labs/CompositionCollectionView/src/Dependencies.props create mode 100644 labs/CompositionCollectionView/src/Themes/Generic.xaml create mode 100644 labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.Uwp/CompositionCollectionView.Tests.Uwp.csproj create mode 100644 labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.Uwp/Package.appxmanifest create mode 100644 labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.Uwp/Properties/AssemblyInfo.cs create mode 100644 labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.Uwp/Properties/Default.rd.xml create mode 100644 labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.WinAppSdk/CompositionCollectionView.Tests.WinAppSdk.csproj create mode 100644 labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.WinAppSdk/Package.appxmanifest create mode 100644 labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.WinAppSdk/Properties/launchSettings.json create mode 100644 labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.WinAppSdk/app.manifest create mode 100644 labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/CompositionCollectionView.Tests.projitems create mode 100644 labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/CompositionCollectionView.Tests.shproj create mode 100644 labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/ExampleCompositionCollectionViewTestClass.cs create mode 100644 labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/ExampleCompositionCollectionViewTestPage.xaml create mode 100644 labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/ExampleCompositionCollectionViewTestPage.xaml.cs diff --git a/labs/CompositionCollectionView/CompositionCollectionView.sln b/labs/CompositionCollectionView/CompositionCollectionView.sln new file mode 100644 index 000000000..0e6ad2716 --- /dev/null +++ b/labs/CompositionCollectionView/CompositionCollectionView.sln @@ -0,0 +1,311 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31919.166 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CommunityToolkit.Labs.WinUI.CompositionCollectionView", "src\CommunityToolkit.Labs.WinUI.CompositionCollectionView.csproj", "{43B832EE-C2B5-4648-B7EE-DD35D4B58CEC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CompositionCollectionView.Uwp", "samples\CompositionCollectionView.Uwp\CompositionCollectionView.Uwp.csproj", "{1FF91978-D8BA-4528-8CC6-D9AB79E734FB}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompositionCollectionView.Wasm", "samples\CompositionCollectionView.Wasm\CompositionCollectionView.Wasm.csproj", "{16334921-9519-4D83-9EB0-A7DC4FB9F355}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompositionCollectionView.Samples", "samples\CompositionCollectionView.Samples\CompositionCollectionView.Samples.csproj", "{91DD91AC-9C40-4E84-AFD1-F1660BFDDB59}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Platforms", "Platforms", "{B8A02B6F-312F-4FF5-98D7-115C8635732B}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompositionCollectionView.WinAppSdk", "samples\CompositionCollectionView.WinAppSdk\CompositionCollectionView.WinAppSdk.csproj", "{77778DBE-302C-4004-B939-1ADB15E421B0}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CommunityToolkit.Labs.Core.SourceGenerators", "..\..\common\CommunityToolkit.Labs.Core.SourceGenerators\CommunityToolkit.Labs.Core.SourceGenerators.csproj", "{66E6DA8A-FEFC-4221-A476-4314A4D692F6}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CommunityToolkit.Labs.Core.SourceGenerators.XamlNamedPropertyRelay", "..\..\common\CommunityToolkit.Labs.Core.SourceGenerators.XamlNamedPropertyRelay\CommunityToolkit.Labs.Core.SourceGenerators.XamlNamedPropertyRelay.csproj", "{7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{CCE58C30-A3E9-4058-83DC-0FB6197F4E07}" +EndProject +Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "CompositionCollectionView.Tests", "tests\CompositionCollectionView.Tests\CompositionCollectionView.Tests.shproj", "{A3D47776-AA76-4032-B5CC-68A25B06796C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompositionCollectionView.Tests.WinAppSdk", "tests\CompositionCollectionView.Tests.WinAppSdk\CompositionCollectionView.Tests.WinAppSdk.csproj", "{2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CompositionCollectionView.Tests.Uwp", "tests\CompositionCollectionView.Tests.Uwp\CompositionCollectionView.Tests.Uwp.csproj", "{3EF11E40-143F-437E-B4C7-3900D5DCF095}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Labs Dependencies", "Labs Dependencies", "{1CB5B668-FD44-4524-8A28-F7057AEC9DF3}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CommunityToolkit.Labs.Core.SourceGenerators.LabsUITestMethod", "..\..\common\CommunityToolkit.Labs.Core.SourceGenerators.LabsUITestMethod\CommunityToolkit.Labs.Core.SourceGenerators.LabsUITestMethod.csproj", "{79F79471-9947-45F5-81FE-4EBE2B8D0B1D}" +EndProject +Global + GlobalSection(SharedMSBuildProjectFiles) = preSolution + tests\CompositionCollectionView.Tests\CompositionCollectionView.Tests.projitems*{a3d47776-aa76-4032-b5cc-68a25b06796c}*SharedItemsImports = 13 + tests\CompositionCollectionView.Tests\CompositionCollectionView.Tests.projitems*{3ef11e40-143f-437e-b4c7-3900d5dcf095}*SharedItemsImports = 4 + ..\..\common\CommunityToolkit.Labs.Shared\CommunityToolkit.Labs.Shared.projitems*{1ff91978-d8ba-4528-8cc6-d9ab79e734fb}*SharedItemsImports = 4 + tests\CompositionCollectionView.Tests\CompositionCollectionView.Tests.projitems*{2f6e208d-6e57-46e5-95d6-bddbf8404cb3}*SharedItemsImports = 5 + EndGlobalSection + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|ARM = Debug|ARM + Debug|ARM64 = Debug|ARM64 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|ARM = Release|ARM + Release|ARM64 = Release|ARM64 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {43B832EE-C2B5-4648-B7EE-DD35D4B58CEC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {43B832EE-C2B5-4648-B7EE-DD35D4B58CEC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {43B832EE-C2B5-4648-B7EE-DD35D4B58CEC}.Debug|ARM.ActiveCfg = Debug|Any CPU + {43B832EE-C2B5-4648-B7EE-DD35D4B58CEC}.Debug|ARM.Build.0 = Debug|Any CPU + {43B832EE-C2B5-4648-B7EE-DD35D4B58CEC}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {43B832EE-C2B5-4648-B7EE-DD35D4B58CEC}.Debug|ARM64.Build.0 = Debug|Any CPU + {43B832EE-C2B5-4648-B7EE-DD35D4B58CEC}.Debug|x64.ActiveCfg = Debug|Any CPU + {43B832EE-C2B5-4648-B7EE-DD35D4B58CEC}.Debug|x64.Build.0 = Debug|Any CPU + {43B832EE-C2B5-4648-B7EE-DD35D4B58CEC}.Debug|x86.ActiveCfg = Debug|Any CPU + {43B832EE-C2B5-4648-B7EE-DD35D4B58CEC}.Debug|x86.Build.0 = Debug|Any CPU + {43B832EE-C2B5-4648-B7EE-DD35D4B58CEC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {43B832EE-C2B5-4648-B7EE-DD35D4B58CEC}.Release|Any CPU.Build.0 = Release|Any CPU + {43B832EE-C2B5-4648-B7EE-DD35D4B58CEC}.Release|ARM.ActiveCfg = Release|Any CPU + {43B832EE-C2B5-4648-B7EE-DD35D4B58CEC}.Release|ARM.Build.0 = Release|Any CPU + {43B832EE-C2B5-4648-B7EE-DD35D4B58CEC}.Release|ARM64.ActiveCfg = Release|Any CPU + {43B832EE-C2B5-4648-B7EE-DD35D4B58CEC}.Release|ARM64.Build.0 = Release|Any CPU + {43B832EE-C2B5-4648-B7EE-DD35D4B58CEC}.Release|x64.ActiveCfg = Release|Any CPU + {43B832EE-C2B5-4648-B7EE-DD35D4B58CEC}.Release|x64.Build.0 = Release|Any CPU + {43B832EE-C2B5-4648-B7EE-DD35D4B58CEC}.Release|x86.ActiveCfg = Release|Any CPU + {43B832EE-C2B5-4648-B7EE-DD35D4B58CEC}.Release|x86.Build.0 = Release|Any CPU + {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Debug|Any CPU.ActiveCfg = Debug|x64 + {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Debug|Any CPU.Build.0 = Debug|x64 + {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Debug|Any CPU.Deploy.0 = Debug|x64 + {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Debug|ARM.ActiveCfg = Debug|ARM + {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Debug|ARM.Build.0 = Debug|ARM + {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Debug|ARM.Deploy.0 = Debug|ARM + {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Debug|ARM64.Build.0 = Debug|ARM64 + {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Debug|x64.ActiveCfg = Debug|x64 + {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Debug|x64.Build.0 = Debug|x64 + {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Debug|x64.Deploy.0 = Debug|x64 + {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Debug|x86.ActiveCfg = Debug|x86 + {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Debug|x86.Build.0 = Debug|x86 + {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Debug|x86.Deploy.0 = Debug|x86 + {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Release|Any CPU.ActiveCfg = Release|x64 + {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Release|Any CPU.Build.0 = Release|x64 + {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Release|Any CPU.Deploy.0 = Release|x64 + {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Release|ARM.ActiveCfg = Release|ARM + {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Release|ARM.Build.0 = Release|ARM + {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Release|ARM.Deploy.0 = Release|ARM + {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Release|ARM64.ActiveCfg = Release|ARM64 + {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Release|ARM64.Build.0 = Release|ARM64 + {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Release|ARM64.Deploy.0 = Release|ARM64 + {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Release|x64.ActiveCfg = Release|x64 + {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Release|x64.Build.0 = Release|x64 + {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Release|x64.Deploy.0 = Release|x64 + {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Release|x86.ActiveCfg = Release|x86 + {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Release|x86.Build.0 = Release|x86 + {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Release|x86.Deploy.0 = Release|x86 + {16334921-9519-4D83-9EB0-A7DC4FB9F355}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {16334921-9519-4D83-9EB0-A7DC4FB9F355}.Debug|Any CPU.Build.0 = Debug|Any CPU + {16334921-9519-4D83-9EB0-A7DC4FB9F355}.Debug|ARM.ActiveCfg = Debug|Any CPU + {16334921-9519-4D83-9EB0-A7DC4FB9F355}.Debug|ARM.Build.0 = Debug|Any CPU + {16334921-9519-4D83-9EB0-A7DC4FB9F355}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {16334921-9519-4D83-9EB0-A7DC4FB9F355}.Debug|ARM64.Build.0 = Debug|Any CPU + {16334921-9519-4D83-9EB0-A7DC4FB9F355}.Debug|x64.ActiveCfg = Debug|Any CPU + {16334921-9519-4D83-9EB0-A7DC4FB9F355}.Debug|x64.Build.0 = Debug|Any CPU + {16334921-9519-4D83-9EB0-A7DC4FB9F355}.Debug|x86.ActiveCfg = Debug|Any CPU + {16334921-9519-4D83-9EB0-A7DC4FB9F355}.Debug|x86.Build.0 = Debug|Any CPU + {16334921-9519-4D83-9EB0-A7DC4FB9F355}.Release|Any CPU.ActiveCfg = Release|Any CPU + {16334921-9519-4D83-9EB0-A7DC4FB9F355}.Release|Any CPU.Build.0 = Release|Any CPU + {16334921-9519-4D83-9EB0-A7DC4FB9F355}.Release|ARM.ActiveCfg = Release|Any CPU + {16334921-9519-4D83-9EB0-A7DC4FB9F355}.Release|ARM.Build.0 = Release|Any CPU + {16334921-9519-4D83-9EB0-A7DC4FB9F355}.Release|ARM64.ActiveCfg = Release|Any CPU + {16334921-9519-4D83-9EB0-A7DC4FB9F355}.Release|ARM64.Build.0 = Release|Any CPU + {16334921-9519-4D83-9EB0-A7DC4FB9F355}.Release|x64.ActiveCfg = Release|Any CPU + {16334921-9519-4D83-9EB0-A7DC4FB9F355}.Release|x64.Build.0 = Release|Any CPU + {16334921-9519-4D83-9EB0-A7DC4FB9F355}.Release|x86.ActiveCfg = Release|Any CPU + {16334921-9519-4D83-9EB0-A7DC4FB9F355}.Release|x86.Build.0 = Release|Any CPU + {91DD91AC-9C40-4E84-AFD1-F1660BFDDB59}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {91DD91AC-9C40-4E84-AFD1-F1660BFDDB59}.Debug|Any CPU.Build.0 = Debug|Any CPU + {91DD91AC-9C40-4E84-AFD1-F1660BFDDB59}.Debug|ARM.ActiveCfg = Debug|Any CPU + {91DD91AC-9C40-4E84-AFD1-F1660BFDDB59}.Debug|ARM.Build.0 = Debug|Any CPU + {91DD91AC-9C40-4E84-AFD1-F1660BFDDB59}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {91DD91AC-9C40-4E84-AFD1-F1660BFDDB59}.Debug|ARM64.Build.0 = Debug|Any CPU + {91DD91AC-9C40-4E84-AFD1-F1660BFDDB59}.Debug|x64.ActiveCfg = Debug|Any CPU + {91DD91AC-9C40-4E84-AFD1-F1660BFDDB59}.Debug|x64.Build.0 = Debug|Any CPU + {91DD91AC-9C40-4E84-AFD1-F1660BFDDB59}.Debug|x86.ActiveCfg = Debug|Any CPU + {91DD91AC-9C40-4E84-AFD1-F1660BFDDB59}.Debug|x86.Build.0 = Debug|Any CPU + {91DD91AC-9C40-4E84-AFD1-F1660BFDDB59}.Release|Any CPU.ActiveCfg = Release|Any CPU + {91DD91AC-9C40-4E84-AFD1-F1660BFDDB59}.Release|Any CPU.Build.0 = Release|Any CPU + {91DD91AC-9C40-4E84-AFD1-F1660BFDDB59}.Release|ARM.ActiveCfg = Release|Any CPU + {91DD91AC-9C40-4E84-AFD1-F1660BFDDB59}.Release|ARM.Build.0 = Release|Any CPU + {91DD91AC-9C40-4E84-AFD1-F1660BFDDB59}.Release|ARM64.ActiveCfg = Release|Any CPU + {91DD91AC-9C40-4E84-AFD1-F1660BFDDB59}.Release|ARM64.Build.0 = Release|Any CPU + {91DD91AC-9C40-4E84-AFD1-F1660BFDDB59}.Release|x64.ActiveCfg = Release|Any CPU + {91DD91AC-9C40-4E84-AFD1-F1660BFDDB59}.Release|x64.Build.0 = Release|Any CPU + {91DD91AC-9C40-4E84-AFD1-F1660BFDDB59}.Release|x86.ActiveCfg = Release|Any CPU + {91DD91AC-9C40-4E84-AFD1-F1660BFDDB59}.Release|x86.Build.0 = Release|Any CPU + {77778DBE-302C-4004-B939-1ADB15E421B0}.Debug|Any CPU.ActiveCfg = Debug|x64 + {77778DBE-302C-4004-B939-1ADB15E421B0}.Debug|Any CPU.Build.0 = Debug|x64 + {77778DBE-302C-4004-B939-1ADB15E421B0}.Debug|Any CPU.Deploy.0 = Debug|x64 + {77778DBE-302C-4004-B939-1ADB15E421B0}.Debug|ARM.ActiveCfg = Debug|x64 + {77778DBE-302C-4004-B939-1ADB15E421B0}.Debug|ARM.Build.0 = Debug|x64 + {77778DBE-302C-4004-B939-1ADB15E421B0}.Debug|ARM.Deploy.0 = Debug|x64 + {77778DBE-302C-4004-B939-1ADB15E421B0}.Debug|ARM64.ActiveCfg = Debug|arm64 + {77778DBE-302C-4004-B939-1ADB15E421B0}.Debug|ARM64.Build.0 = Debug|arm64 + {77778DBE-302C-4004-B939-1ADB15E421B0}.Debug|ARM64.Deploy.0 = Debug|arm64 + {77778DBE-302C-4004-B939-1ADB15E421B0}.Debug|x64.ActiveCfg = Debug|x64 + {77778DBE-302C-4004-B939-1ADB15E421B0}.Debug|x64.Build.0 = Debug|x64 + {77778DBE-302C-4004-B939-1ADB15E421B0}.Debug|x64.Deploy.0 = Debug|x64 + {77778DBE-302C-4004-B939-1ADB15E421B0}.Debug|x86.ActiveCfg = Debug|x86 + {77778DBE-302C-4004-B939-1ADB15E421B0}.Debug|x86.Build.0 = Debug|x86 + {77778DBE-302C-4004-B939-1ADB15E421B0}.Debug|x86.Deploy.0 = Debug|x86 + {77778DBE-302C-4004-B939-1ADB15E421B0}.Release|Any CPU.ActiveCfg = Release|x64 + {77778DBE-302C-4004-B939-1ADB15E421B0}.Release|Any CPU.Build.0 = Release|x64 + {77778DBE-302C-4004-B939-1ADB15E421B0}.Release|Any CPU.Deploy.0 = Release|x64 + {77778DBE-302C-4004-B939-1ADB15E421B0}.Release|ARM.ActiveCfg = Release|x64 + {77778DBE-302C-4004-B939-1ADB15E421B0}.Release|ARM.Build.0 = Release|x64 + {77778DBE-302C-4004-B939-1ADB15E421B0}.Release|ARM.Deploy.0 = Release|x64 + {77778DBE-302C-4004-B939-1ADB15E421B0}.Release|ARM64.ActiveCfg = Release|arm64 + {77778DBE-302C-4004-B939-1ADB15E421B0}.Release|ARM64.Build.0 = Release|arm64 + {77778DBE-302C-4004-B939-1ADB15E421B0}.Release|ARM64.Deploy.0 = Release|arm64 + {77778DBE-302C-4004-B939-1ADB15E421B0}.Release|x64.ActiveCfg = Release|x64 + {77778DBE-302C-4004-B939-1ADB15E421B0}.Release|x64.Build.0 = Release|x64 + {77778DBE-302C-4004-B939-1ADB15E421B0}.Release|x64.Deploy.0 = Release|x64 + {77778DBE-302C-4004-B939-1ADB15E421B0}.Release|x86.ActiveCfg = Release|x86 + {77778DBE-302C-4004-B939-1ADB15E421B0}.Release|x86.Build.0 = Release|x86 + {77778DBE-302C-4004-B939-1ADB15E421B0}.Release|x86.Deploy.0 = Release|x86 + {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Debug|ARM.ActiveCfg = Debug|Any CPU + {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Debug|ARM.Build.0 = Debug|Any CPU + {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Debug|ARM64.Build.0 = Debug|Any CPU + {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Debug|x64.ActiveCfg = Debug|Any CPU + {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Debug|x64.Build.0 = Debug|Any CPU + {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Debug|x86.ActiveCfg = Debug|Any CPU + {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Debug|x86.Build.0 = Debug|Any CPU + {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Release|Any CPU.Build.0 = Release|Any CPU + {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Release|ARM.ActiveCfg = Release|Any CPU + {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Release|ARM.Build.0 = Release|Any CPU + {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Release|ARM64.ActiveCfg = Release|Any CPU + {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Release|ARM64.Build.0 = Release|Any CPU + {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Release|x64.ActiveCfg = Release|Any CPU + {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Release|x64.Build.0 = Release|Any CPU + {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Release|x86.ActiveCfg = Release|Any CPU + {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Release|x86.Build.0 = Release|Any CPU + {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Debug|ARM.ActiveCfg = Debug|Any CPU + {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Debug|ARM.Build.0 = Debug|Any CPU + {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Debug|ARM64.Build.0 = Debug|Any CPU + {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Debug|x64.ActiveCfg = Debug|Any CPU + {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Debug|x64.Build.0 = Debug|Any CPU + {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Debug|x86.ActiveCfg = Debug|Any CPU + {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Debug|x86.Build.0 = Debug|Any CPU + {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Release|Any CPU.Build.0 = Release|Any CPU + {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Release|ARM.ActiveCfg = Release|Any CPU + {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Release|ARM.Build.0 = Release|Any CPU + {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Release|ARM64.ActiveCfg = Release|Any CPU + {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Release|ARM64.Build.0 = Release|Any CPU + {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Release|x64.ActiveCfg = Release|Any CPU + {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Release|x64.Build.0 = Release|Any CPU + {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Release|x86.ActiveCfg = Release|Any CPU + {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Release|x86.Build.0 = Release|Any CPU + {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Debug|Any CPU.ActiveCfg = Debug|x64 + {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Debug|Any CPU.Build.0 = Debug|x64 + {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Debug|Any CPU.Deploy.0 = Debug|x64 + {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Debug|ARM.ActiveCfg = Debug|x64 + {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Debug|ARM.Build.0 = Debug|x64 + {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Debug|ARM.Deploy.0 = Debug|x64 + {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Debug|ARM64.ActiveCfg = Debug|arm64 + {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Debug|ARM64.Build.0 = Debug|arm64 + {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Debug|ARM64.Deploy.0 = Debug|arm64 + {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Debug|x64.ActiveCfg = Debug|x64 + {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Debug|x64.Build.0 = Debug|x64 + {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Debug|x64.Deploy.0 = Debug|x64 + {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Debug|x86.ActiveCfg = Debug|x86 + {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Debug|x86.Build.0 = Debug|x86 + {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Debug|x86.Deploy.0 = Debug|x86 + {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Release|Any CPU.ActiveCfg = Release|x64 + {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Release|Any CPU.Build.0 = Release|x64 + {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Release|Any CPU.Deploy.0 = Release|x64 + {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Release|ARM.ActiveCfg = Release|x64 + {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Release|ARM.Build.0 = Release|x64 + {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Release|ARM.Deploy.0 = Release|x64 + {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Release|ARM64.ActiveCfg = Release|arm64 + {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Release|ARM64.Build.0 = Release|arm64 + {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Release|ARM64.Deploy.0 = Release|arm64 + {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Release|x64.ActiveCfg = Release|x64 + {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Release|x64.Build.0 = Release|x64 + {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Release|x64.Deploy.0 = Release|x64 + {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Release|x86.ActiveCfg = Release|x86 + {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Release|x86.Build.0 = Release|x86 + {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Release|x86.Deploy.0 = Release|x86 + {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Debug|Any CPU.ActiveCfg = Debug|x64 + {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Debug|Any CPU.Build.0 = Debug|x64 + {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Debug|Any CPU.Deploy.0 = Debug|x64 + {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Debug|ARM.ActiveCfg = Debug|ARM + {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Debug|ARM.Build.0 = Debug|ARM + {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Debug|ARM.Deploy.0 = Debug|ARM + {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Debug|ARM64.Build.0 = Debug|ARM64 + {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Debug|x64.ActiveCfg = Debug|x64 + {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Debug|x64.Build.0 = Debug|x64 + {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Debug|x64.Deploy.0 = Debug|x64 + {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Debug|x86.ActiveCfg = Debug|x86 + {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Debug|x86.Build.0 = Debug|x86 + {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Debug|x86.Deploy.0 = Debug|x86 + {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Release|Any CPU.ActiveCfg = Release|x64 + {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Release|Any CPU.Build.0 = Release|x64 + {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Release|Any CPU.Deploy.0 = Release|x64 + {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Release|ARM.ActiveCfg = Release|ARM + {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Release|ARM.Build.0 = Release|ARM + {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Release|ARM.Deploy.0 = Release|ARM + {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Release|ARM64.ActiveCfg = Release|ARM64 + {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Release|ARM64.Build.0 = Release|ARM64 + {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Release|ARM64.Deploy.0 = Release|ARM64 + {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Release|x64.ActiveCfg = Release|x64 + {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Release|x64.Build.0 = Release|x64 + {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Release|x64.Deploy.0 = Release|x64 + {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Release|x86.ActiveCfg = Release|x86 + {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Release|x86.Build.0 = Release|x86 + {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Release|x86.Deploy.0 = Release|x86 + {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Debug|ARM.ActiveCfg = Debug|Any CPU + {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Debug|ARM.Build.0 = Debug|Any CPU + {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Debug|ARM64.Build.0 = Debug|Any CPU + {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Debug|x64.ActiveCfg = Debug|Any CPU + {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Debug|x64.Build.0 = Debug|Any CPU + {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Debug|x86.ActiveCfg = Debug|Any CPU + {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Debug|x86.Build.0 = Debug|Any CPU + {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Release|Any CPU.Build.0 = Release|Any CPU + {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Release|ARM.ActiveCfg = Release|Any CPU + {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Release|ARM.Build.0 = Release|Any CPU + {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Release|ARM64.ActiveCfg = Release|Any CPU + {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Release|ARM64.Build.0 = Release|Any CPU + {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Release|x64.ActiveCfg = Release|Any CPU + {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Release|x64.Build.0 = Release|Any CPU + {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Release|x86.ActiveCfg = Release|Any CPU + {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {1FF91978-D8BA-4528-8CC6-D9AB79E734FB} = {B8A02B6F-312F-4FF5-98D7-115C8635732B} + {16334921-9519-4D83-9EB0-A7DC4FB9F355} = {B8A02B6F-312F-4FF5-98D7-115C8635732B} + {77778DBE-302C-4004-B939-1ADB15E421B0} = {B8A02B6F-312F-4FF5-98D7-115C8635732B} + {66E6DA8A-FEFC-4221-A476-4314A4D692F6} = {1CB5B668-FD44-4524-8A28-F7057AEC9DF3} + {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91} = {1CB5B668-FD44-4524-8A28-F7057AEC9DF3} + {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3} = {CCE58C30-A3E9-4058-83DC-0FB6197F4E07} + {3EF11E40-143F-437E-B4C7-3900D5DCF095} = {CCE58C30-A3E9-4058-83DC-0FB6197F4E07} + {79F79471-9947-45F5-81FE-4EBE2B8D0B1D} = {1CB5B668-FD44-4524-8A28-F7057AEC9DF3} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {69A3A187-4290-4A0A-9FD6-F491BDAAC5BF} + EndGlobalSection +EndGlobal diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionView.Samples.csproj b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionView.Samples.csproj new file mode 100644 index 000000000..c52936a10 --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionView.Samples.csproj @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + CompositionCollectionViewExperiment.Samples + CompositionCollectionViewExperiment.Samples + + + + + + + + diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionView.md b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionView.md new file mode 100644 index 000000000..11c2d9e3a --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionView.md @@ -0,0 +1,64 @@ +--- +title: CompositionCollectionView +author: githubaccount +description: TODO: Your experiment's description here +keywords: CompositionCollectionView, Control, Layout +dev_langs: + - csharp +category: Controls +subcategory: Layout +--- + + + + + + + +# CompositionCollectionView + +For more information about this experiment see: +- Discussion: TODO: PASTE LINK HERE +- Issue: TODO: PASTE LINK HERE + +TODO: Fill in information about this experiment and how to get started here... + +## Custom Control + +You can inherit from an existing component as well, like `Panel`, this example shows a control without a +XAML Style that will be more light-weight to consume by an app developer: + +> [!Sample CompositionCollectionViewCustomSample] + +## Templated Controls + +The Toolkit is built with templated controls. This provides developers a flexible way to restyle components +easily while still inheriting the general functionality a control provides. The examples below show +how a component can use a default style and then get overridden by the end developer. + +TODO: Two types of templated control building methods are shown. Delete these if you're building a custom component. +Otherwise, pick one method for your component and delete the files related to the unchosen `_ClassicBinding` or `_xBind` +classes (and the custom non-suffixed one as well). Then, rename your component to just be your component name. + +The `_ClassicBinding` class shows the traditional method used to develop components with best practices. + +### Implict style + +> [!SAMPLE CompositionCollectionViewTemplatedSample] + +### Custom style + +> [!SAMPLE CompositionCollectionViewTemplatedStyleCustomSample] + +## Templated Controls with x:Bind + +This is an _experimental_ new way to define components which allows for the use of x:Bind within the style. + +### Implict style + +> [!SAMPLE CompositionCollectionViewXbindBackedSample] + +### Custom style + +> [!SAMPLE CompositionCollectionViewXbindBackedStyleCustomSample] + diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewCustomSample.xaml b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewCustomSample.xaml new file mode 100644 index 000000000..e41262f94 --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewCustomSample.xaml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewCustomSample.xaml.cs b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewCustomSample.xaml.cs new file mode 100644 index 000000000..0190b54da --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewCustomSample.xaml.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace CompositionCollectionViewExperiment.Samples; + +/// +/// An example sample page of a custom control inheriting from Panel. +/// +[ToolkitSampleMultiChoiceOption("LayoutOrientation", title: "Orientation", "Horizontal", "Vertical")] + +[ToolkitSample(id: nameof(CompositionCollectionViewCustomSample), "Custom control", description: $"A sample for showing how to create and use a {nameof(CompositionCollectionView)} custom control.")] +public sealed partial class CompositionCollectionViewCustomSample : Page +{ + public CompositionCollectionViewCustomSample() + { + this.InitializeComponent(); + } + + // TODO: See https://github.com/CommunityToolkit/Labs-Windows/issues/149 + public static Orientation ConvertStringToOrientation(string orientation) => orientation switch + { + "Vertical" => Orientation.Vertical, + "Horizontal" => Orientation.Horizontal, + _ => throw new System.NotImplementedException(), + }; +} diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewTemplatedSample.xaml b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewTemplatedSample.xaml new file mode 100644 index 000000000..87fea9050 --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewTemplatedSample.xaml @@ -0,0 +1,16 @@ + + + + + + + diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewTemplatedSample.xaml.cs b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewTemplatedSample.xaml.cs new file mode 100644 index 000000000..28400ded7 --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewTemplatedSample.xaml.cs @@ -0,0 +1,24 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace CompositionCollectionViewExperiment.Samples; + +[ToolkitSampleBoolOption("IsTextVisible", "IsVisible", true)] +// Single values without a colon are used for both label and value. +// To provide a different label for the value, separate with a colon surrounded by a single space on both sides ("label : value"). +[ToolkitSampleMultiChoiceOption("TextSize", title: "Text size", "Small : 12", "Normal : 16", "Big : 32")] +[ToolkitSampleMultiChoiceOption("TextFontFamily", title: "Font family", "Segoe UI", "Arial", "Consolas")] +[ToolkitSampleMultiChoiceOption("TextForeground", title: "Text foreground", + "Teal : #0ddc8c", + "Sand : #e7a676", + "Dull green : #5d7577")] + +[ToolkitSample(id: nameof(CompositionCollectionViewTemplatedSample), "Templated control", description: "A sample for showing how to create and use a templated control.")] +public sealed partial class CompositionCollectionViewTemplatedSample : Page +{ + public CompositionCollectionViewTemplatedSample() + { + this.InitializeComponent(); + } +} diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewTemplatedStyleCustomSample.xaml b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewTemplatedStyleCustomSample.xaml new file mode 100644 index 000000000..48ce03fdd --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewTemplatedStyleCustomSample.xaml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewTemplatedStyleCustomSample.xaml.cs b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewTemplatedStyleCustomSample.xaml.cs new file mode 100644 index 000000000..a3930d6f2 --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewTemplatedStyleCustomSample.xaml.cs @@ -0,0 +1,24 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace CompositionCollectionViewExperiment.Samples; + +[ToolkitSampleBoolOption("IsTextVisible", "IsVisible", true)] +// Single values without a colon are used for both label and value. +// To provide a different label for the value, separate with a colon surrounded by a single space on both sides ("label : value"). +[ToolkitSampleMultiChoiceOption("TextSize", title: "Text size", "Small : 12", "Normal : 16", "Big : 32")] +[ToolkitSampleMultiChoiceOption("TextFontFamily", title: "Font family", "Segoe UI", "Arial", "Consolas")] +[ToolkitSampleMultiChoiceOption("TextForeground", title: "Text foreground", + "Teal : #0ddc8c", + "Sand : #e7a676", + "Dull green : #5d7577")] + +[ToolkitSample(id: nameof(CompositionCollectionViewTemplatedStyleCustomSample), "Templated control (restyled)", description: "A sample for showing how to create a use and templated control with a custom style.")] +public sealed partial class CompositionCollectionViewTemplatedStyleCustomSample : Page +{ + public CompositionCollectionViewTemplatedStyleCustomSample() + { + this.InitializeComponent(); + } +} diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewXbindBackedSample.xaml b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewXbindBackedSample.xaml new file mode 100644 index 000000000..45955404c --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewXbindBackedSample.xaml @@ -0,0 +1,16 @@ + + + + + + + diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewXbindBackedSample.xaml.cs b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewXbindBackedSample.xaml.cs new file mode 100644 index 000000000..d91b368ad --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewXbindBackedSample.xaml.cs @@ -0,0 +1,24 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace CompositionCollectionViewExperiment.Samples; + +[ToolkitSampleBoolOption("IsTextVisible", "IsVisible", true)] +// Single values without a colon are used for both label and value. +// To provide a different label for the value, separate with a colon surrounded by a single space on both sides ("label : value"). +[ToolkitSampleMultiChoiceOption("TextSize", title: "Text size", "Small : 12", "Normal : 16", "Big : 32")] +[ToolkitSampleMultiChoiceOption("TextFontFamily", title: "Font family", "Segoe UI", "Arial", "Consolas")] +[ToolkitSampleMultiChoiceOption("TextForeground", title: "Text foreground", + "Teal : #0ddc8c", + "Sand : #e7a676", + "Dull green : #5d7577")] + +[ToolkitSample(id: nameof(CompositionCollectionViewXbindBackedSample), "Backed templated control", description: "A sample for showing how to create and use a templated control with a backed resource dictionary.")] +public sealed partial class CompositionCollectionViewXbindBackedSample : Page +{ + public CompositionCollectionViewXbindBackedSample() + { + this.InitializeComponent(); + } +} diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewXbindBackedStyleCustomSample.xaml b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewXbindBackedStyleCustomSample.xaml new file mode 100644 index 000000000..2e955e442 --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewXbindBackedStyleCustomSample.xaml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewXbindBackedStyleCustomSample.xaml.cs b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewXbindBackedStyleCustomSample.xaml.cs new file mode 100644 index 000000000..01bca3b14 --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewXbindBackedStyleCustomSample.xaml.cs @@ -0,0 +1,24 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace CompositionCollectionViewExperiment.Samples; + +[ToolkitSampleBoolOption("IsTextVisible", "IsVisible", true)] +// Single values without a colon are used for both label and value. +// To provide a different label for the value, separate with a colon surrounded by a single space on both sides ("label : value"). +[ToolkitSampleMultiChoiceOption("TextSize", title: "Text size", "Small : 12", "Normal : 16", "Big : 32")] +[ToolkitSampleMultiChoiceOption("TextFontFamily", title: "Font family", "Segoe UI", "Arial", "Consolas")] +[ToolkitSampleMultiChoiceOption("TextForeground", title: "Text foreground", + "Teal : #0ddc8c", + "Sand : #e7a676", + "Dull green : #5d7577")] + +[ToolkitSample(id: nameof(CompositionCollectionViewXbindBackedStyleCustomSample), "Backed templated control (restyled)", description: "A sample for showing how to create and use a templated control with a backed resource dictionary and a custom style.")] +public sealed partial class CompositionCollectionViewXbindBackedStyleCustomSample : Page +{ + public CompositionCollectionViewXbindBackedStyleCustomSample() + { + this.InitializeComponent(); + } +} diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/Dependencies.props b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/Dependencies.props new file mode 100644 index 000000000..e622e1df4 --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/Dependencies.props @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Uwp/CompositionCollectionView.Uwp.csproj b/labs/CompositionCollectionView/samples/CompositionCollectionView.Uwp/CompositionCollectionView.Uwp.csproj new file mode 100644 index 000000000..1888b407a --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Uwp/CompositionCollectionView.Uwp.csproj @@ -0,0 +1,61 @@ + + + + + + + + true + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + + + + + + + + + + + CompositionCollectionViewExperiment.Samples + CompositionCollectionViewExperiment.Samples.Uwp + {1FF91978-D8BA-4528-8CC6-D9AB79E734FB} + + + + + + + + + + Designer + + + + + {43B832EE-C2B5-4648-B7EE-DD35D4B58CEC} + CommunityToolkit.Labs.WinUI.CompositionCollectionView + + + {91DD91AC-9C40-4E84-AFD1-F1660BFDDB59} + CompositionCollectionView.Sample + + + + + \ No newline at end of file diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Uwp/Package.appxmanifest b/labs/CompositionCollectionView/samples/CompositionCollectionView.Uwp/Package.appxmanifest new file mode 100644 index 000000000..2148ed375 --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Uwp/Package.appxmanifest @@ -0,0 +1,49 @@ + + + + + + + + + + CommunityToolkit Labs: CompositionCollectionView Samples (UWP) + CommunityToolkit + Assets\StoreLogo.png + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Uwp/Properties/AssemblyInfo.cs b/labs/CompositionCollectionView/samples/CompositionCollectionView.Uwp/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..0851e6170 --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Uwp/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("CommunityToolkit.Labs.Uwp.Samples.CompositionCollectionView")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany(".NET Foundation")] +[assembly: AssemblyProduct("CommunityToolkit.Labs.Uwp.Samples.CompositionCollectionView")] +[assembly: AssemblyCopyright("Copyright © .NET Foundation 2022")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: ComVisible(false)] diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Uwp/Properties/Default.rd.xml b/labs/CompositionCollectionView/samples/CompositionCollectionView.Uwp/Properties/Default.rd.xml new file mode 100644 index 000000000..af00722cd --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Uwp/Properties/Default.rd.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/CompositionCollectionView.Wasm.csproj b/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/CompositionCollectionView.Wasm.csproj new file mode 100644 index 000000000..6f62190a3 --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/CompositionCollectionView.Wasm.csproj @@ -0,0 +1,41 @@ + + + + + true + true + true + false + false + false + false + false + false + false + false + false + false + false + false + false + + + + + + + + + + + + + + + + + + + + + diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/Program.cs b/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/Program.cs new file mode 100644 index 000000000..41c789347 --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/Program.cs @@ -0,0 +1,19 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using CommunityToolkit.Labs.Shared; + +namespace CompositionCollectionViewExperiment.Samples.Wasm; + +public class Program +{ + private static App? _app; + + static int Main(string[] args) + { + Application.Start(_ => _app = new App()); + + return 0; + } +} diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/Properties/launchSettings.json b/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/Properties/launchSettings.json new file mode 100644 index 000000000..33b0e52e0 --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/Properties/launchSettings.json @@ -0,0 +1,27 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:50720/", + "sslPort": 44326 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "CompositionCollectionView.Wasm": { + "commandName": "Project", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "https://localhost:5001;http://localhost:5000" + } + } +} diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/WasmCSS/Fonts.css b/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/WasmCSS/Fonts.css new file mode 100644 index 000000000..56618162a --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/WasmCSS/Fonts.css @@ -0,0 +1,27 @@ +/** + When adding fonts here, make sure to add them using a base64 data uri, otherwise + fonts loading are delayed, and text may get displayed incorrectly. +*/ + +@font-face { + font-family: "Symbols"; + /* uno-fluentui-assets.woff2 */ + src: url(data:application/x-font-woff;charset=utf-8;base64,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)format('woff'); +} + + +/* Workaround for uno issue https://github.com/unoplatform/uno/issues/693 */ +body::before { + font-family: 'Symbols'; + background: transparent; + content: ""; + opacity: 0; + pointer-events: none; + position: absolute; +} + +/* https://github.com/unoplatform/uno/issues/4304 */ +@font-face { + font-family: 'Segoe UI'; + src: local('system-ui'), local('Segoe UI'), local('-apple-system'), local('BlinkMacSystemFont'), local('Inter'), local('Cantarell'), local('Ubuntu'), local('Roboto'), local('Open Sans'), local('Noto Sans'), local('Helvetica Neue'), local('sans-serif'); +} \ No newline at end of file diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/WasmScripts/AppManifest.js b/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/WasmScripts/AppManifest.js new file mode 100644 index 000000000..185d1d38d --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/WasmScripts/AppManifest.js @@ -0,0 +1,5 @@ +var UnoAppManifest = { + splashScreenImage: "Assets/SplashScreen.png", + splashScreenColor: "#fff", + displayName: "Labs: CompositionCollectionView" +} diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/wwwroot/web.config b/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/wwwroot/web.config new file mode 100644 index 000000000..8f5a860f5 --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/wwwroot/web.config @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.WinAppSdk/CompositionCollectionView.WinAppSdk.csproj b/labs/CompositionCollectionView/samples/CompositionCollectionView.WinAppSdk/CompositionCollectionView.WinAppSdk.csproj new file mode 100644 index 000000000..cd5e53a62 --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.WinAppSdk/CompositionCollectionView.WinAppSdk.csproj @@ -0,0 +1,46 @@ + + + + + true + false + false + false + false + false + false + false + false + true + false + false + false + false + false + false + + + + + + + + + + + CompositionCollectionViewExperiment.Samples + CompositionCollectionViewExperiment.Samples.WinAppSdk + + + + + + + + + + + + diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.WinAppSdk/Package.appxmanifest b/labs/CompositionCollectionView/samples/CompositionCollectionView.WinAppSdk/Package.appxmanifest new file mode 100644 index 000000000..73268eaaf --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.WinAppSdk/Package.appxmanifest @@ -0,0 +1,49 @@ + + + + + + + + CommunityToolkit Labs: CompositionCollectionView Samples (WinAppSdk) + CommunityToolkit + Assets\StoreLogo.png + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.WinAppSdk/Properties/launchSettings.json b/labs/CompositionCollectionView/samples/CompositionCollectionView.WinAppSdk/Properties/launchSettings.json new file mode 100644 index 000000000..f06823289 --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.WinAppSdk/Properties/launchSettings.json @@ -0,0 +1,10 @@ +{ + "profiles": { + "Local machine (Packaged)": { + "commandName": "MsixPackage" + }, + "Local machine (Unpackaged)": { + "commandName": "Project" + } + } +} \ No newline at end of file diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.WinAppSdk/app.manifest b/labs/CompositionCollectionView/samples/CompositionCollectionView.WinAppSdk/app.manifest new file mode 100644 index 000000000..04ff2978a --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.WinAppSdk/app.manifest @@ -0,0 +1,15 @@ + + + + + + + + true/PM + PerMonitorV2, PerMonitor + + + diff --git a/labs/CompositionCollectionView/src/AdditionalAssemblyInfo.cs b/labs/CompositionCollectionView/src/AdditionalAssemblyInfo.cs new file mode 100644 index 000000000..5ba7ccac3 --- /dev/null +++ b/labs/CompositionCollectionView/src/AdditionalAssemblyInfo.cs @@ -0,0 +1,13 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Runtime.CompilerServices; + +// These `InternalsVisibleTo` calls are intended to make it easier for +// for any internal code to be testable in all the different test projects +// used with the Labs infrastructure. +[assembly: InternalsVisibleTo("CompositionCollectionView.Tests.Uwp")] +[assembly: InternalsVisibleTo("CompositionCollectionView.Tests.WinAppSdk")] +[assembly: InternalsVisibleTo("CommunityToolkit.Labs.Tests.Uwp")] +[assembly: InternalsVisibleTo("CommunityToolkit.Labs.Tests.WinAppSdk")] diff --git a/labs/CompositionCollectionView/src/CommunityToolkit.Labs.WinUI.CompositionCollectionView.csproj b/labs/CompositionCollectionView/src/CommunityToolkit.Labs.WinUI.CompositionCollectionView.csproj new file mode 100644 index 000000000..597d55ecf --- /dev/null +++ b/labs/CompositionCollectionView/src/CommunityToolkit.Labs.WinUI.CompositionCollectionView.csproj @@ -0,0 +1,25 @@ + + + + + + + + + + + + + CommunityToolkit.Labs.WinUI.CompositionCollectionViewRns + + + + CommunityToolkit.Labs.$(PackageIdVariant).CompositionCollectionView + + This package contains CompositionCollectionView. + + 0.0.1 + + + + diff --git a/labs/CompositionCollectionView/src/CompositionCollectionView.cs b/labs/CompositionCollectionView/src/CompositionCollectionView.cs new file mode 100644 index 000000000..8ba04efd6 --- /dev/null +++ b/labs/CompositionCollectionView/src/CompositionCollectionView.cs @@ -0,0 +1,108 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace CommunityToolkit.Labs.WinUI; + +/// +/// This is an example control based off of the BoxPanel sample here: https://docs.microsoft.com/windows/apps/design/layout/boxpanel-example-custom-panel. If you need this similar sort of layout component for an application, see UniformGrid in the Toolkit. +/// It is provided as an example of how to inherit from another control like . +/// You can choose to start here or from the or example components. Remove unused components and rename as appropriate. +/// +public partial class CompositionCollectionView : Panel +{ + /// + /// Identifies the property. + /// + public static readonly DependencyProperty OrientationProperty = + DependencyProperty.Register(nameof(Orientation), typeof(Orientation), typeof(CompositionCollectionView), new PropertyMetadata(null, OnOrientationChanged)); + + /// + /// Gets the preference of the rows/columns when there are a non-square number of children. Defaults to Vertical. + /// + public Orientation Orientation + { + get { return (Orientation)GetValue(OrientationProperty); } + set { SetValue(OrientationProperty, value); } + } + + // Invalidate our layout when the property changes. + private static void OnOrientationChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args) + { + if (dependencyObject is CompositionCollectionView panel) + { + panel.InvalidateMeasure(); + } + } + + // Store calculations we want to use between the Measure and Arrange methods. + int _columnCount; + double _cellWidth, _cellHeight; + + protected override Size MeasureOverride(Size availableSize) + { + // Determine the square that can contain this number of items. + var maxrc = (int)Math.Ceiling(Math.Sqrt(Children.Count)); + // Get an aspect ratio from availableSize, decides whether to trim row or column. + var aspectratio = availableSize.Width / availableSize.Height; + if (Orientation == Orientation.Vertical) { aspectratio = 1 / aspectratio; } + + int rowcount; + + // Now trim this square down to a rect, many times an entire row or column can be omitted. + if (aspectratio > 1) + { + rowcount = maxrc; + _columnCount = (maxrc > 2 && Children.Count <= maxrc * (maxrc - 1)) ? maxrc - 1 : maxrc; + } + else + { + rowcount = (maxrc > 2 && Children.Count <= maxrc * (maxrc - 1)) ? maxrc - 1 : maxrc; + _columnCount = maxrc; + } + + // Now that we have a column count, divide available horizontal, that's our cell width. + _cellWidth = (int)Math.Floor(availableSize.Width / _columnCount); + // Next get a cell height, same logic of dividing available vertical by rowcount. + _cellHeight = Double.IsInfinity(availableSize.Height) ? Double.PositiveInfinity : availableSize.Height / rowcount; + + double maxcellheight = 0; + + foreach (UIElement child in Children) + { + child.Measure(new Size(_cellWidth, _cellHeight)); + maxcellheight = (child.DesiredSize.Height > maxcellheight) ? child.DesiredSize.Height : maxcellheight; + } + + return LimitUnboundedSize(availableSize, maxcellheight); + } + + // This method limits the panel height when no limit is imposed by the panel's parent. + // That can happen to height if the panel is close to the root of main app window. + // In this case, base the height of a cell on the max height from desired size + // and base the height of the panel on that number times the #rows. + Size LimitUnboundedSize(Size input, double maxcellheight) + { + if (Double.IsInfinity(input.Height)) + { + input.Height = maxcellheight * _columnCount; + _cellHeight = maxcellheight; + } + return input; + } + + protected override Size ArrangeOverride(Size finalSize) + { + int count = 1; + double x, y; + foreach (UIElement child in Children) + { + x = (count - 1) % _columnCount * _cellWidth; + y = ((int)(count - 1) / _columnCount) * _cellHeight; + Point anchorPoint = new Point(x, y); + child.Arrange(new Rect(anchorPoint, child.DesiredSize)); + count++; + } + return finalSize; + } +} diff --git a/labs/CompositionCollectionView/src/CompositionCollectionViewStyle_ClassicBinding.xaml b/labs/CompositionCollectionView/src/CompositionCollectionViewStyle_ClassicBinding.xaml new file mode 100644 index 000000000..053433573 --- /dev/null +++ b/labs/CompositionCollectionView/src/CompositionCollectionViewStyle_ClassicBinding.xaml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + 4,4,4,4 + + + + + + + + diff --git a/labs/CompositionCollectionView/src/CompositionCollectionViewStyle_xBind.xaml b/labs/CompositionCollectionView/src/CompositionCollectionViewStyle_xBind.xaml new file mode 100644 index 000000000..0fc5d5e77 --- /dev/null +++ b/labs/CompositionCollectionView/src/CompositionCollectionViewStyle_xBind.xaml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + 4,4,4,4 + + + + + + + + diff --git a/labs/CompositionCollectionView/src/CompositionCollectionViewStyle_xBind.xaml.cs b/labs/CompositionCollectionView/src/CompositionCollectionViewStyle_xBind.xaml.cs new file mode 100644 index 000000000..e9d5914d5 --- /dev/null +++ b/labs/CompositionCollectionView/src/CompositionCollectionViewStyle_xBind.xaml.cs @@ -0,0 +1,20 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace CommunityToolkit.Labs.WinUI; + +/// +/// Backing code for this resource dictionary. +/// +public sealed partial class CompositionCollectionViewStyle_xBind : ResourceDictionary +{ + // NOTICE + // This file only exists to enable x:Bind in the resource dictionary. + // Do not add code here. + // Instead, add code-behind to your templated control. + public CompositionCollectionViewStyle_xBind() + { + this.InitializeComponent(); + } +} diff --git a/labs/CompositionCollectionView/src/CompositionCollectionView_ClassicBinding.cs b/labs/CompositionCollectionView/src/CompositionCollectionView_ClassicBinding.cs new file mode 100644 index 000000000..41550ff53 --- /dev/null +++ b/labs/CompositionCollectionView/src/CompositionCollectionView_ClassicBinding.cs @@ -0,0 +1,94 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace CommunityToolkit.Labs.WinUI; + +/// +/// An example templated control. +/// +[TemplatePart(Name = nameof(PART_HelloWorld), Type = typeof(TextBlock))] +public partial class CompositionCollectionView_ClassicBinding : Control +{ + /// + /// Creates a new instance of the class. + /// + public CompositionCollectionView_ClassicBinding() + { + this.DefaultStyleKey = typeof(CompositionCollectionView_ClassicBinding); + } + + /// + /// The primary text block that displays "Hello world". + /// + protected TextBlock? PART_HelloWorld { get; private set; } + + /// + protected override void OnApplyTemplate() + { + base.OnApplyTemplate(); + + // Detach all attached events when a new template is applied. + if (PART_HelloWorld is not null) + { + PART_HelloWorld.PointerEntered -= Element_PointerEntered; + } + + // Attach events when the template is applied and the control is loaded. + PART_HelloWorld = GetTemplateChild(nameof(PART_HelloWorld)) as TextBlock; + + if (PART_HelloWorld is not null) + { + PART_HelloWorld.PointerEntered += Element_PointerEntered; + } + } + + /// + /// The backing for the property. + /// + public static readonly DependencyProperty ItemPaddingProperty = DependencyProperty.Register( + nameof(ItemPadding), + typeof(Thickness), + typeof(CompositionCollectionView_ClassicBinding), + new PropertyMetadata(defaultValue: new Thickness(0))); + + /// + /// The backing for the property. + /// + public static readonly DependencyProperty MyPropertyProperty = DependencyProperty.Register( + nameof(MyProperty), + typeof(string), + typeof(CompositionCollectionView_ClassicBinding), + new PropertyMetadata(defaultValue: string.Empty, (d, e) => ((CompositionCollectionView_ClassicBinding)d).OnMyPropertyChanged((string)e.OldValue, (string)e.NewValue))); + + /// + /// Gets or sets an example string. A basic DependencyProperty example. + /// + public string MyProperty + { + get => (string)GetValue(MyPropertyProperty); + set => SetValue(MyPropertyProperty, value); + } + + /// + /// Gets or sets a padding for an item. A basic DependencyProperty example. + /// + public Thickness ItemPadding + { + get => (Thickness)GetValue(ItemPaddingProperty); + set => SetValue(ItemPaddingProperty, value); + } + + protected virtual void OnMyPropertyChanged(string oldValue, string newValue) + { + // Do something with the changed value. + } + + public void Element_PointerEntered(object sender, PointerRoutedEventArgs e) + { + if (sender is TextBlock text) + { + text.Opacity = 1; + } + } +} diff --git a/labs/CompositionCollectionView/src/CompositionCollectionView_xBind.cs b/labs/CompositionCollectionView/src/CompositionCollectionView_xBind.cs new file mode 100644 index 000000000..95bb7ee77 --- /dev/null +++ b/labs/CompositionCollectionView/src/CompositionCollectionView_xBind.cs @@ -0,0 +1,71 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace CommunityToolkit.Labs.WinUI; + +/// +/// An example templated control. +/// +public partial class CompositionCollectionView_xBind: Control +{ + /// + /// Creates a new instance of the class. + /// + public CompositionCollectionView_xBind() + { + this.DefaultStyleKey = typeof(CompositionCollectionView_xBind); + + // Allows directly using this control as the x:DataType in the template. + this.DataContext = this; + } + + /// + /// The backing for the property. + /// + public static readonly DependencyProperty ItemPaddingProperty = DependencyProperty.Register( + nameof(ItemPadding), + typeof(Thickness), + typeof(CompositionCollectionView_xBind), + new PropertyMetadata(defaultValue: new Thickness(0))); + + /// + /// The backing for the property. + /// + public static readonly DependencyProperty MyPropertyProperty = DependencyProperty.Register( + nameof(MyProperty), + typeof(string), + typeof(CompositionCollectionView_xBind), + new PropertyMetadata(defaultValue: string.Empty, (d, e) => ((CompositionCollectionView_xBind)d).OnMyPropertyChanged((string)e.OldValue, (string)e.NewValue))); + + /// + /// Gets or sets an example string. A basic DependencyProperty example. + /// + public string MyProperty + { + get => (string)GetValue(MyPropertyProperty); + set => SetValue(MyPropertyProperty, value); + } + + /// + /// Gets or sets a padding for an item. A basic DependencyProperty example. + /// + public Thickness ItemPadding + { + get => (Thickness)GetValue(ItemPaddingProperty); + set => SetValue(ItemPaddingProperty, value); + } + + protected virtual void OnMyPropertyChanged(string oldValue, string newValue) + { + // Do something with the changed value. + } + + public void Element_PointerEntered(object sender, PointerRoutedEventArgs e) + { + if (sender is TextBlock text) + { + text.Opacity = 1; + } + } +} diff --git a/labs/CompositionCollectionView/src/Dependencies.props b/labs/CompositionCollectionView/src/Dependencies.props new file mode 100644 index 000000000..e622e1df4 --- /dev/null +++ b/labs/CompositionCollectionView/src/Dependencies.props @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/labs/CompositionCollectionView/src/Themes/Generic.xaml b/labs/CompositionCollectionView/src/Themes/Generic.xaml new file mode 100644 index 000000000..71848ab11 --- /dev/null +++ b/labs/CompositionCollectionView/src/Themes/Generic.xaml @@ -0,0 +1,10 @@ + + + + + + + + diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.Uwp/CompositionCollectionView.Tests.Uwp.csproj b/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.Uwp/CompositionCollectionView.Tests.Uwp.csproj new file mode 100644 index 000000000..fca26409a --- /dev/null +++ b/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.Uwp/CompositionCollectionView.Tests.Uwp.csproj @@ -0,0 +1,61 @@ + + + + + + + + true + + + + + + + + + + + {3EF11E40-143F-437E-B4C7-3900D5DCF095} + CompositionCollectionViewExperiment.Tests + CompositionCollectionViewExperiment.Tests.Uwp + $(VisualStudioVersion) + + + + + + + Designer + + + + + Assets\LockScreenLogo.png + + + Assets\Square150x150Logo.png + + + Assets\Square44x44Logo.png + + + Assets\Square44x44Logo.targetsize-24_altform-unplated.png + + + Assets\StoreLogo.png + + + + + + + + + + + + + + + diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.Uwp/Package.appxmanifest b/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.Uwp/Package.appxmanifest new file mode 100644 index 000000000..8bd839a02 --- /dev/null +++ b/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.Uwp/Package.appxmanifest @@ -0,0 +1,47 @@ + + + + + + + + + CompositionCollectionViewExperiment.Tests.Uwp + CommunityToolkit + Assets\StoreLogo.png + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.Uwp/Properties/AssemblyInfo.cs b/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.Uwp/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..a86521f30 --- /dev/null +++ b/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.Uwp/Properties/AssemblyInfo.cs @@ -0,0 +1,22 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle("CompositionCollectionViewExperiment.Tests.Uwp")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany(".NET Foundation")] +[assembly: AssemblyProduct("CompositionCollectionViewExperiment.Tests.Uwp")] +[assembly: AssemblyCopyright("Copyright © .NET Foundation 2022")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +[assembly: AssemblyMetadata("TargetPlatform","UAP")] + +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: ComVisible(false)] \ No newline at end of file diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.Uwp/Properties/Default.rd.xml b/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.Uwp/Properties/Default.rd.xml new file mode 100644 index 000000000..996a8392a --- /dev/null +++ b/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.Uwp/Properties/Default.rd.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.WinAppSdk/CompositionCollectionView.Tests.WinAppSdk.csproj b/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.WinAppSdk/CompositionCollectionView.Tests.WinAppSdk.csproj new file mode 100644 index 000000000..d6dbf8579 --- /dev/null +++ b/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.WinAppSdk/CompositionCollectionView.Tests.WinAppSdk.csproj @@ -0,0 +1,43 @@ + + + + + true + + + + + + + + + + + CompositionCollectionViewExperiment.Tests + CompositionCollectionViewExperiment.Tests.WinAppSdk + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.WinAppSdk/Package.appxmanifest b/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.WinAppSdk/Package.appxmanifest new file mode 100644 index 000000000..aa2818b44 --- /dev/null +++ b/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.WinAppSdk/Package.appxmanifest @@ -0,0 +1,48 @@ + + + + + + + + CompositionCollectionViewExperiment.Tests.WinAppSdk + CommunityToolkit + Assets\StoreLogo.png + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.WinAppSdk/Properties/launchSettings.json b/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.WinAppSdk/Properties/launchSettings.json new file mode 100644 index 000000000..b5d7775c6 --- /dev/null +++ b/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.WinAppSdk/Properties/launchSettings.json @@ -0,0 +1,10 @@ +{ + "profiles": { + "CompositionCollectionView.Tests.WinAppSdk (Package)": { + "commandName": "MsixPackage" + }, + "CompositionCollectionView.Tests.WinAppSdk (Unpackaged)": { + "commandName": "Project" + } + } +} diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.WinAppSdk/app.manifest b/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.WinAppSdk/app.manifest new file mode 100644 index 000000000..84b8521ee --- /dev/null +++ b/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.WinAppSdk/app.manifest @@ -0,0 +1,15 @@ + + + + + + + + true/PM + PerMonitorV2, PerMonitor + + + diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/CompositionCollectionView.Tests.projitems b/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/CompositionCollectionView.Tests.projitems new file mode 100644 index 000000000..4b6b90f72 --- /dev/null +++ b/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/CompositionCollectionView.Tests.projitems @@ -0,0 +1,23 @@ + + + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) + true + A3D47776-AA76-4032-B5CC-68A25B06796C + + + CompositionCollectionViewExperiment.Tests + + + + + ExampleCompositionCollectionViewTestPage.xaml + + + + + Designer + MSBuild:Compile + + + \ No newline at end of file diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/CompositionCollectionView.Tests.shproj b/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/CompositionCollectionView.Tests.shproj new file mode 100644 index 000000000..90c42dc27 --- /dev/null +++ b/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/CompositionCollectionView.Tests.shproj @@ -0,0 +1,13 @@ + + + + A3D47776-AA76-4032-B5CC-68A25B06796C + 14.0 + + + + + + + + diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/ExampleCompositionCollectionViewTestClass.cs b/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/ExampleCompositionCollectionViewTestClass.cs new file mode 100644 index 000000000..372f1761c --- /dev/null +++ b/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/ExampleCompositionCollectionViewTestClass.cs @@ -0,0 +1,132 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using CommunityToolkit.Labs.Core.SourceGenerators.LabsUITestMethod; +using CommunityToolkit.Labs.Tests; + +namespace CompositionCollectionViewExperiment.Tests; + +[TestClass] +public partial class ExampleCompositionCollectionViewTestClass : VisualUITestBase +{ + // If you don't need access to UI objects directly or async code, use this pattern. + [TestMethod] + public void SimpleSynchronousExampleTest() + { + var assembly = typeof(CompositionCollectionView).Assembly; + var type = assembly.GetType(typeof(CompositionCollectionView).FullName ?? string.Empty); + + Assert.IsNotNull(type, "Could not find CompositionCollectionView type."); + Assert.AreEqual(typeof(CompositionCollectionView), type, "Type of CompositionCollectionView does not match expected type."); + } + + // If you don't need access to UI objects directly, use this pattern. + [TestMethod] + public async Task SimpleAsyncExampleTest() + { + await Task.Delay(250); + + Assert.IsTrue(true); + } + + // Example that shows how to check for exception throwing. + [TestMethod] + public void SimpleExceptionCheckTest() + { + // If you need to check exceptions occur for invalid inputs, etc... + // Use Assert.ThrowsException to limit the scope to where you expect the error to occur. + // Otherwise, using the ExpectedException attribute could swallow or + // catch other issues in setup code. + Assert.ThrowsException(() => throw new NotImplementedException()); + } + + // The LabsUITestMethod automatically dispatches to the UI for us to work with UI objects. + [LabsUITestMethod] + public void SimpleUIAttributeExampleTest() + { + var component = new CompositionCollectionView(); + Assert.IsNotNull(component); + } + + // The LabsUITestMethod can also easily grab a XAML Page for us by passing its type as a parameter. + // This lets us actually test a control as it would behave within an actual application. + // The page will already be loaded by the time your test is called. + [LabsUITestMethod] + public void SimpleUIExamplePageTest(ExampleCompositionCollectionViewTestPage page) + { + // You can use the Toolkit Visual Tree helpers here to find the component by type or name: + var component = page.FindDescendant(); + + Assert.IsNotNull(component); + + var componentByName = page.FindDescendant("CompositionCollectionViewControl"); + + Assert.IsNotNull(componentByName); + } + + // You can still do async work with a LabsUITestMethod as well. + [LabsUITestMethod] + public async Task SimpleAsyncUIExamplePageTest(ExampleCompositionCollectionViewTestPage page) + { + // This helper can be used to wait for a rendering pass to complete. + await CompositionTargetHelper.ExecuteAfterCompositionRenderingAsync(() => { }); + + var component = page.FindDescendant(); + + Assert.IsNotNull(component); + } + + //// ----------------------------- ADVANCED TEST SCENARIOS ----------------------------- + + // If you need to use DataRow, you can use this pattern with the UI dispatch still. + // Otherwise, checkout the LabsUITestMethod attribute above. + // See https://github.com/CommunityToolkit/Labs-Windows/issues/186 + [TestMethod] + public async Task ComplexAsyncUIExampleTest() + { + await EnqueueAsync(() => + { + var component = new CompositionCollectionView_ClassicBinding(); + Assert.IsNotNull(component); + }); + } + + // If you want to load other content not within a XAML page using the LabsUITestMethod above. + // Then you can do that using the Load/UnloadTestContentAsync methods. + [TestMethod] + public async Task ComplexAsyncLoadUIExampleTest() + { + await EnqueueAsync(async () => + { + var component = new CompositionCollectionView_ClassicBinding(); + Assert.IsNotNull(component); + Assert.IsFalse(component.IsLoaded); + + await LoadTestContentAsync(component); + + Assert.IsTrue(component.IsLoaded); + + await UnloadTestContentAsync(component); + + Assert.IsFalse(component.IsLoaded); + }); + } + + // You can still use the LabsUITestMethod to remove the extra layer for the dispatcher as well: + [LabsUITestMethod] + public async Task ComplexAsyncLoadUIExampleWithoutDispatcherTest() + { + var component = new CompositionCollectionView_ClassicBinding(); + Assert.IsNotNull(component); + Assert.IsFalse(component.IsLoaded); + + await LoadTestContentAsync(component); + + Assert.IsTrue(component.IsLoaded); + + await UnloadTestContentAsync(component); + + Assert.IsFalse(component.IsLoaded); + } +} diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/ExampleCompositionCollectionViewTestPage.xaml b/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/ExampleCompositionCollectionViewTestPage.xaml new file mode 100644 index 000000000..09a72853a --- /dev/null +++ b/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/ExampleCompositionCollectionViewTestPage.xaml @@ -0,0 +1,14 @@ + + + + + + + diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/ExampleCompositionCollectionViewTestPage.xaml.cs b/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/ExampleCompositionCollectionViewTestPage.xaml.cs new file mode 100644 index 000000000..a98600d02 --- /dev/null +++ b/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/ExampleCompositionCollectionViewTestPage.xaml.cs @@ -0,0 +1,16 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace CompositionCollectionViewExperiment.Tests; + +/// +/// An empty page that can be used on its own or navigated to within a Frame. +/// +public sealed partial class ExampleCompositionCollectionViewTestPage : Page +{ + public ExampleCompositionCollectionViewTestPage() + { + this.InitializeComponent(); + } +} From 11a1a4350bee9f8b5c58c1d602e95dd8affca345 Mon Sep 17 00:00:00 2001 From: Arcadio Garcia Salvadores Date: Mon, 5 Sep 2022 17:16:46 -0700 Subject: [PATCH 05/44] Fix maze layout --- .../CompositionCollectionView.sln | 35 +- .../Assets/wall.png | Bin 30238 -> 0 bytes .../Assets/ceiling.bmp | Bin .../Assets/floor.bmp | Bin .../Assets/wall.bmp | Bin .../CompositionCollectionView.Samples.csproj | 6 + .../CompositionCollectionView.md | 40 -- ...CompositionCollectionViewCustomSample.xaml | 21 - ...positionCollectionViewCustomSample.xaml.cs | 27 -- ...positionCollectionViewFirstSamplePage.xaml | 0 ...itionCollectionViewFirstSamplePage.xaml.cs | 89 ++++ ...positionCollectionViewTemplatedSample.xaml | 16 - ...itionCollectionViewTemplatedSample.xaml.cs | 24 -- ...lectionViewTemplatedStyleCustomSample.xaml | 26 -- ...tionViewTemplatedStyleCustomSample.xaml.cs | 24 -- ...sitionCollectionViewXbindBackedSample.xaml | 16 - ...ionCollectionViewXbindBackedSample.xaml.cs | 24 -- ...ctionViewXbindBackedStyleCustomSample.xaml | 26 -- ...onViewXbindBackedStyleCustomSample.xaml.cs | 24 -- .../InteractionTrackerSample.xaml | 0 .../InteractionTrackerSample.xaml.cs | 166 ++++++++ .../MazeSample.xaml | 0 .../MazeSample.xaml.cs | 398 ++++++++++++++++++ .../SwitchLayoutsSample.xaml | 0 .../SwitchLayoutsSample.xaml.cs | 140 ++++++ ...abs.WinUI.CompositionCollectionView.csproj | 24 +- ...ionCollectionViewStyle_ClassicBinding.xaml | 62 --- .../CompositionCollectionViewStyle_xBind.xaml | 69 --- ...mpositionCollectionViewStyle_xBind.xaml.cs | 20 - ...ompositionCollectionView_ClassicBinding.cs | 94 ----- .../src/CompositionCollectionView_xBind.cs | 71 ---- .../src/Themes/Generic.xaml | 5 - 32 files changed, 831 insertions(+), 616 deletions(-) delete mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/Assets/wall.png rename labs/CompositionCollectionView/samples/{CompositionCollectionView.Sample => CompositionCollectionView.Samples}/Assets/ceiling.bmp (100%) rename labs/CompositionCollectionView/samples/{CompositionCollectionView.Sample => CompositionCollectionView.Samples}/Assets/floor.bmp (100%) rename labs/CompositionCollectionView/samples/{CompositionCollectionView.Sample => CompositionCollectionView.Samples}/Assets/wall.bmp (100%) delete mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewCustomSample.xaml delete mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewCustomSample.xaml.cs rename labs/CompositionCollectionView/samples/{CompositionCollectionView.Sample => CompositionCollectionView.Samples}/CompositionCollectionViewFirstSamplePage.xaml (100%) create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewFirstSamplePage.xaml.cs delete mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewTemplatedSample.xaml delete mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewTemplatedSample.xaml.cs delete mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewTemplatedStyleCustomSample.xaml delete mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewTemplatedStyleCustomSample.xaml.cs delete mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewXbindBackedSample.xaml delete mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewXbindBackedSample.xaml.cs delete mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewXbindBackedStyleCustomSample.xaml delete mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewXbindBackedStyleCustomSample.xaml.cs rename labs/CompositionCollectionView/samples/{CompositionCollectionView.Sample => CompositionCollectionView.Samples}/InteractionTrackerSample.xaml (100%) create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/InteractionTrackerSample.xaml.cs rename labs/CompositionCollectionView/samples/{CompositionCollectionView.Sample => CompositionCollectionView.Samples}/MazeSample.xaml (100%) create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/MazeSample.xaml.cs rename labs/CompositionCollectionView/samples/{CompositionCollectionView.Sample => CompositionCollectionView.Samples}/SwitchLayoutsSample.xaml (100%) create mode 100644 labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/SwitchLayoutsSample.xaml.cs delete mode 100644 labs/CompositionCollectionView/src/CompositionCollectionViewStyle_ClassicBinding.xaml delete mode 100644 labs/CompositionCollectionView/src/CompositionCollectionViewStyle_xBind.xaml delete mode 100644 labs/CompositionCollectionView/src/CompositionCollectionViewStyle_xBind.xaml.cs delete mode 100644 labs/CompositionCollectionView/src/CompositionCollectionView_ClassicBinding.cs delete mode 100644 labs/CompositionCollectionView/src/CompositionCollectionView_xBind.cs diff --git a/labs/CompositionCollectionView/CompositionCollectionView.sln b/labs/CompositionCollectionView/CompositionCollectionView.sln index 89c6aa334..bb284783c 100644 --- a/labs/CompositionCollectionView/CompositionCollectionView.sln +++ b/labs/CompositionCollectionView/CompositionCollectionView.sln @@ -1,4 +1,3 @@ - Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.0.31919.166 @@ -31,13 +30,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Labs Dependencies", "Labs D EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CommunityToolkit.Labs.Core.SourceGenerators.LabsUITestMethod", "..\..\common\CommunityToolkit.Labs.Core.SourceGenerators.LabsUITestMethod\CommunityToolkit.Labs.Core.SourceGenerators.LabsUITestMethod.csproj", "{79F79471-9947-45F5-81FE-4EBE2B8D0B1D}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExpressionsFork", "ExpressionsFork\ExpressionsFork.csproj", "{1E97AC9F-CB43-4B98-AEF9-2BA035E037A7}" +EndProject Global - GlobalSection(SharedMSBuildProjectFiles) = preSolution - tests\CompositionCollectionView.Tests\CompositionCollectionView.Tests.projitems*{a3d47776-aa76-4032-b5cc-68a25b06796c}*SharedItemsImports = 13 - tests\CompositionCollectionView.Tests\CompositionCollectionView.Tests.projitems*{3ef11e40-143f-437e-b4c7-3900d5dcf095}*SharedItemsImports = 4 - ..\..\common\CommunityToolkit.Labs.Shared\CommunityToolkit.Labs.Shared.projitems*{1ff91978-d8ba-4528-8cc6-d9ab79e734fb}*SharedItemsImports = 4 - tests\CompositionCollectionView.Tests\CompositionCollectionView.Tests.projitems*{2f6e208d-6e57-46e5-95d6-bddbf8404cb3}*SharedItemsImports = 5 - EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Debug|ARM = Debug|ARM @@ -291,6 +286,26 @@ Global {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Release|x64.Build.0 = Release|Any CPU {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Release|x86.ActiveCfg = Release|Any CPU {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Release|x86.Build.0 = Release|Any CPU + {1E97AC9F-CB43-4B98-AEF9-2BA035E037A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1E97AC9F-CB43-4B98-AEF9-2BA035E037A7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1E97AC9F-CB43-4B98-AEF9-2BA035E037A7}.Debug|ARM.ActiveCfg = Debug|ARM + {1E97AC9F-CB43-4B98-AEF9-2BA035E037A7}.Debug|ARM.Build.0 = Debug|ARM + {1E97AC9F-CB43-4B98-AEF9-2BA035E037A7}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {1E97AC9F-CB43-4B98-AEF9-2BA035E037A7}.Debug|ARM64.Build.0 = Debug|ARM64 + {1E97AC9F-CB43-4B98-AEF9-2BA035E037A7}.Debug|x64.ActiveCfg = Debug|Any CPU + {1E97AC9F-CB43-4B98-AEF9-2BA035E037A7}.Debug|x64.Build.0 = Debug|Any CPU + {1E97AC9F-CB43-4B98-AEF9-2BA035E037A7}.Debug|x86.ActiveCfg = Debug|x86 + {1E97AC9F-CB43-4B98-AEF9-2BA035E037A7}.Debug|x86.Build.0 = Debug|x86 + {1E97AC9F-CB43-4B98-AEF9-2BA035E037A7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1E97AC9F-CB43-4B98-AEF9-2BA035E037A7}.Release|Any CPU.Build.0 = Release|Any CPU + {1E97AC9F-CB43-4B98-AEF9-2BA035E037A7}.Release|ARM.ActiveCfg = Release|ARM + {1E97AC9F-CB43-4B98-AEF9-2BA035E037A7}.Release|ARM.Build.0 = Release|ARM + {1E97AC9F-CB43-4B98-AEF9-2BA035E037A7}.Release|ARM64.ActiveCfg = Release|ARM64 + {1E97AC9F-CB43-4B98-AEF9-2BA035E037A7}.Release|ARM64.Build.0 = Release|ARM64 + {1E97AC9F-CB43-4B98-AEF9-2BA035E037A7}.Release|x64.ActiveCfg = Release|x64 + {1E97AC9F-CB43-4B98-AEF9-2BA035E037A7}.Release|x64.Build.0 = Release|x64 + {1E97AC9F-CB43-4B98-AEF9-2BA035E037A7}.Release|x86.ActiveCfg = Release|x86 + {1E97AC9F-CB43-4B98-AEF9-2BA035E037A7}.Release|x86.Build.0 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -308,4 +323,10 @@ Global GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {69A3A187-4290-4A0A-9FD6-F491BDAAC5BF} EndGlobalSection + GlobalSection(SharedMSBuildProjectFiles) = preSolution + ..\..\common\CommunityToolkit.Labs.Shared\CommunityToolkit.Labs.Shared.projitems*{1ff91978-d8ba-4528-8cc6-d9ab79e734fb}*SharedItemsImports = 4 + tests\CompositionCollectionView.Tests\CompositionCollectionView.Tests.projitems*{2f6e208d-6e57-46e5-95d6-bddbf8404cb3}*SharedItemsImports = 5 + tests\CompositionCollectionView.Tests\CompositionCollectionView.Tests.projitems*{3ef11e40-143f-437e-b4c7-3900d5dcf095}*SharedItemsImports = 4 + tests\CompositionCollectionView.Tests\CompositionCollectionView.Tests.projitems*{a3d47776-aa76-4032-b5cc-68a25b06796c}*SharedItemsImports = 13 + EndGlobalSection EndGlobal diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/Assets/wall.png b/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/Assets/wall.png deleted file mode 100644 index 995dd4b59be4322fbb306c4dc7214d351a91f706..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30238 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 Ef{hDlRsaA1 diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/Assets/ceiling.bmp b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/Assets/ceiling.bmp similarity index 100% rename from labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/Assets/ceiling.bmp rename to labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/Assets/ceiling.bmp diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/Assets/floor.bmp b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/Assets/floor.bmp similarity index 100% rename from labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/Assets/floor.bmp rename to labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/Assets/floor.bmp diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/Assets/wall.bmp b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/Assets/wall.bmp similarity index 100% rename from labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/Assets/wall.bmp rename to labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/Assets/wall.bmp diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionView.Samples.csproj b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionView.Samples.csproj index c52936a10..96760853e 100644 --- a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionView.Samples.csproj +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionView.Samples.csproj @@ -17,6 +17,12 @@ + + + + + + diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionView.md b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionView.md index 11c2d9e3a..1150f42b2 100644 --- a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionView.md +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionView.md @@ -22,43 +22,3 @@ For more information about this experiment see: - Issue: TODO: PASTE LINK HERE TODO: Fill in information about this experiment and how to get started here... - -## Custom Control - -You can inherit from an existing component as well, like `Panel`, this example shows a control without a -XAML Style that will be more light-weight to consume by an app developer: - -> [!Sample CompositionCollectionViewCustomSample] - -## Templated Controls - -The Toolkit is built with templated controls. This provides developers a flexible way to restyle components -easily while still inheriting the general functionality a control provides. The examples below show -how a component can use a default style and then get overridden by the end developer. - -TODO: Two types of templated control building methods are shown. Delete these if you're building a custom component. -Otherwise, pick one method for your component and delete the files related to the unchosen `_ClassicBinding` or `_xBind` -classes (and the custom non-suffixed one as well). Then, rename your component to just be your component name. - -The `_ClassicBinding` class shows the traditional method used to develop components with best practices. - -### Implict style - -> [!SAMPLE CompositionCollectionViewTemplatedSample] - -### Custom style - -> [!SAMPLE CompositionCollectionViewTemplatedStyleCustomSample] - -## Templated Controls with x:Bind - -This is an _experimental_ new way to define components which allows for the use of x:Bind within the style. - -### Implict style - -> [!SAMPLE CompositionCollectionViewXbindBackedSample] - -### Custom style - -> [!SAMPLE CompositionCollectionViewXbindBackedStyleCustomSample] - diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewCustomSample.xaml b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewCustomSample.xaml deleted file mode 100644 index e41262f94..000000000 --- a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewCustomSample.xaml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewCustomSample.xaml.cs b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewCustomSample.xaml.cs deleted file mode 100644 index 0190b54da..000000000 --- a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewCustomSample.xaml.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace CompositionCollectionViewExperiment.Samples; - -/// -/// An example sample page of a custom control inheriting from Panel. -/// -[ToolkitSampleMultiChoiceOption("LayoutOrientation", title: "Orientation", "Horizontal", "Vertical")] - -[ToolkitSample(id: nameof(CompositionCollectionViewCustomSample), "Custom control", description: $"A sample for showing how to create and use a {nameof(CompositionCollectionView)} custom control.")] -public sealed partial class CompositionCollectionViewCustomSample : Page -{ - public CompositionCollectionViewCustomSample() - { - this.InitializeComponent(); - } - - // TODO: See https://github.com/CommunityToolkit/Labs-Windows/issues/149 - public static Orientation ConvertStringToOrientation(string orientation) => orientation switch - { - "Vertical" => Orientation.Vertical, - "Horizontal" => Orientation.Horizontal, - _ => throw new System.NotImplementedException(), - }; -} diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/CompositionCollectionViewFirstSamplePage.xaml b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewFirstSamplePage.xaml similarity index 100% rename from labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/CompositionCollectionViewFirstSamplePage.xaml rename to labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewFirstSamplePage.xaml diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewFirstSamplePage.xaml.cs b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewFirstSamplePage.xaml.cs new file mode 100644 index 000000000..5d704e72b --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewFirstSamplePage.xaml.cs @@ -0,0 +1,89 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +using CommunityToolkit.Labs.Core.SourceGenerators; +using CommunityToolkit.Labs.Core.SourceGenerators.Attributes; +using CommunityToolkit.Labs.WinUI.CompositionCollectionView; +using Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork; + +#if !WINAPPSDK +using Windows.Foundation; +using Windows.Foundation.Collections; +using Windows.UI.Composition; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Controls.Primitives; +using Windows.UI.Xaml.Data; +using Windows.UI.Xaml.Input; +using Windows.UI.Xaml.Media; +using Windows.UI.Xaml.Navigation; +using Windows.UI.Xaml.Shapes; +#else +using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Controls; +using Microsoft.UI.Xaml.Controls.Primitives; +using Microsoft.UI.Xaml.Data; +using Microsoft.UI.Xaml.Input; +using Microsoft.UI.Xaml.Media; +using Microsoft.UI.Xaml.Navigation; +#endif + + +namespace CompositionCollectionView.Sample +{ + [ToolkitSample(id: nameof(CompositionCollectionViewFirstSamplePage), "Simple layout", description: "Displaying elements in a simple layout.")] + public sealed partial class CompositionCollectionViewFirstSamplePage : Page + { + private List<(uint, Action>)> elements { get; init; } = new() + { + (0, (_, _)=>{ }), + (1, (_, _)=>{ }), + (2, (_, _)=>{ }), + (3, (_, _)=>{ }) + }; + + public CompositionCollectionViewFirstSamplePage() + { + this.InitializeComponent(); + + var layout = new SampleLayout((id) => + new Rectangle() + { + Width = 100, + Height = 100, + Fill = new SolidColorBrush(Windows.UI.Colors.BlueViolet) + } + , (_) => { }); + compositionCollectionView.SetLayout(layout); + compositionCollectionView.UpdateSource(elements); + } + + public class SampleLayout : Layout + { + public SampleLayout(Func elementFactory, Action log) : base(elementFactory, log) + { + } + + public override Vector3Node GetElementPositionNode(ElementReference element) + { + return ExpressionFunctions.Vector3(element.Id * 120, 0, 0); + } + + public override ScalarNode GetElementScaleNode(ElementReference element) => 1; + + protected override void ConfigureElement(ElementReference element) + { + } + + public override void UpdateElement(ElementReference element) + { + } + } + + private void Button_Click_Add(object sender, RoutedEventArgs e) + { + elements.Add(((uint)elements.Count, (_, _) => { })); + compositionCollectionView.UpdateSource(elements); + } + } +} diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewTemplatedSample.xaml b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewTemplatedSample.xaml deleted file mode 100644 index 87fea9050..000000000 --- a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewTemplatedSample.xaml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewTemplatedSample.xaml.cs b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewTemplatedSample.xaml.cs deleted file mode 100644 index 28400ded7..000000000 --- a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewTemplatedSample.xaml.cs +++ /dev/null @@ -1,24 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace CompositionCollectionViewExperiment.Samples; - -[ToolkitSampleBoolOption("IsTextVisible", "IsVisible", true)] -// Single values without a colon are used for both label and value. -// To provide a different label for the value, separate with a colon surrounded by a single space on both sides ("label : value"). -[ToolkitSampleMultiChoiceOption("TextSize", title: "Text size", "Small : 12", "Normal : 16", "Big : 32")] -[ToolkitSampleMultiChoiceOption("TextFontFamily", title: "Font family", "Segoe UI", "Arial", "Consolas")] -[ToolkitSampleMultiChoiceOption("TextForeground", title: "Text foreground", - "Teal : #0ddc8c", - "Sand : #e7a676", - "Dull green : #5d7577")] - -[ToolkitSample(id: nameof(CompositionCollectionViewTemplatedSample), "Templated control", description: "A sample for showing how to create and use a templated control.")] -public sealed partial class CompositionCollectionViewTemplatedSample : Page -{ - public CompositionCollectionViewTemplatedSample() - { - this.InitializeComponent(); - } -} diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewTemplatedStyleCustomSample.xaml b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewTemplatedStyleCustomSample.xaml deleted file mode 100644 index 48ce03fdd..000000000 --- a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewTemplatedStyleCustomSample.xaml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewTemplatedStyleCustomSample.xaml.cs b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewTemplatedStyleCustomSample.xaml.cs deleted file mode 100644 index a3930d6f2..000000000 --- a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewTemplatedStyleCustomSample.xaml.cs +++ /dev/null @@ -1,24 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace CompositionCollectionViewExperiment.Samples; - -[ToolkitSampleBoolOption("IsTextVisible", "IsVisible", true)] -// Single values without a colon are used for both label and value. -// To provide a different label for the value, separate with a colon surrounded by a single space on both sides ("label : value"). -[ToolkitSampleMultiChoiceOption("TextSize", title: "Text size", "Small : 12", "Normal : 16", "Big : 32")] -[ToolkitSampleMultiChoiceOption("TextFontFamily", title: "Font family", "Segoe UI", "Arial", "Consolas")] -[ToolkitSampleMultiChoiceOption("TextForeground", title: "Text foreground", - "Teal : #0ddc8c", - "Sand : #e7a676", - "Dull green : #5d7577")] - -[ToolkitSample(id: nameof(CompositionCollectionViewTemplatedStyleCustomSample), "Templated control (restyled)", description: "A sample for showing how to create a use and templated control with a custom style.")] -public sealed partial class CompositionCollectionViewTemplatedStyleCustomSample : Page -{ - public CompositionCollectionViewTemplatedStyleCustomSample() - { - this.InitializeComponent(); - } -} diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewXbindBackedSample.xaml b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewXbindBackedSample.xaml deleted file mode 100644 index 45955404c..000000000 --- a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewXbindBackedSample.xaml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewXbindBackedSample.xaml.cs b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewXbindBackedSample.xaml.cs deleted file mode 100644 index d91b368ad..000000000 --- a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewXbindBackedSample.xaml.cs +++ /dev/null @@ -1,24 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace CompositionCollectionViewExperiment.Samples; - -[ToolkitSampleBoolOption("IsTextVisible", "IsVisible", true)] -// Single values without a colon are used for both label and value. -// To provide a different label for the value, separate with a colon surrounded by a single space on both sides ("label : value"). -[ToolkitSampleMultiChoiceOption("TextSize", title: "Text size", "Small : 12", "Normal : 16", "Big : 32")] -[ToolkitSampleMultiChoiceOption("TextFontFamily", title: "Font family", "Segoe UI", "Arial", "Consolas")] -[ToolkitSampleMultiChoiceOption("TextForeground", title: "Text foreground", - "Teal : #0ddc8c", - "Sand : #e7a676", - "Dull green : #5d7577")] - -[ToolkitSample(id: nameof(CompositionCollectionViewXbindBackedSample), "Backed templated control", description: "A sample for showing how to create and use a templated control with a backed resource dictionary.")] -public sealed partial class CompositionCollectionViewXbindBackedSample : Page -{ - public CompositionCollectionViewXbindBackedSample() - { - this.InitializeComponent(); - } -} diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewXbindBackedStyleCustomSample.xaml b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewXbindBackedStyleCustomSample.xaml deleted file mode 100644 index 2e955e442..000000000 --- a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewXbindBackedStyleCustomSample.xaml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewXbindBackedStyleCustomSample.xaml.cs b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewXbindBackedStyleCustomSample.xaml.cs deleted file mode 100644 index 01bca3b14..000000000 --- a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionViewXbindBackedStyleCustomSample.xaml.cs +++ /dev/null @@ -1,24 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace CompositionCollectionViewExperiment.Samples; - -[ToolkitSampleBoolOption("IsTextVisible", "IsVisible", true)] -// Single values without a colon are used for both label and value. -// To provide a different label for the value, separate with a colon surrounded by a single space on both sides ("label : value"). -[ToolkitSampleMultiChoiceOption("TextSize", title: "Text size", "Small : 12", "Normal : 16", "Big : 32")] -[ToolkitSampleMultiChoiceOption("TextFontFamily", title: "Font family", "Segoe UI", "Arial", "Consolas")] -[ToolkitSampleMultiChoiceOption("TextForeground", title: "Text foreground", - "Teal : #0ddc8c", - "Sand : #e7a676", - "Dull green : #5d7577")] - -[ToolkitSample(id: nameof(CompositionCollectionViewXbindBackedStyleCustomSample), "Backed templated control (restyled)", description: "A sample for showing how to create and use a templated control with a backed resource dictionary and a custom style.")] -public sealed partial class CompositionCollectionViewXbindBackedStyleCustomSample : Page -{ - public CompositionCollectionViewXbindBackedStyleCustomSample() - { - this.InitializeComponent(); - } -} diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/InteractionTrackerSample.xaml b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/InteractionTrackerSample.xaml similarity index 100% rename from labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/InteractionTrackerSample.xaml rename to labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/InteractionTrackerSample.xaml diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/InteractionTrackerSample.xaml.cs b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/InteractionTrackerSample.xaml.cs new file mode 100644 index 000000000..2abcc31ce --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/InteractionTrackerSample.xaml.cs @@ -0,0 +1,166 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +using CommunityToolkit.Labs.Core.SourceGenerators; +using CommunityToolkit.Labs.Core.SourceGenerators.Attributes; +using CommunityToolkit.Labs.WinUI.CompositionCollectionView; +using Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork; +using System.Numerics; + +#if !WINAPPSDK +using Windows.Foundation; +using Windows.Foundation.Collections; +using Windows.UI; +using Windows.UI.Composition; +using Windows.UI.Composition.Interactions; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Controls.Primitives; +using Windows.UI.Xaml.Data; +using Windows.UI.Xaml.Hosting; +using Windows.UI.Xaml.Input; +using Windows.UI.Xaml.Media; +using Windows.UI.Xaml.Navigation; +using Windows.UI.Xaml.Shapes; +#else +using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Controls; +using Microsoft.UI.Xaml.Controls.Primitives; +using Microsoft.UI.Xaml.Data; +using Microsoft.UI.Xaml.Input; +using Microsoft.UI.Xaml.Media; +using Microsoft.UI.Xaml.Navigation; +#endif + + +namespace CompositionCollectionView.Sample +{ + [ToolkitSample(id: nameof(InteractionTrackerSample), "Interaction tracker layout", description: "Layout driven by an interaction tracker.")] + public sealed partial class InteractionTrackerSample : Page + { + const int ElementWidth = 100; + + private List<(uint, Action>)> elements { get; init; } = new() + { + (0, (_, _)=>{ }), + (1, (_, _)=>{ }), + (2, (_, _)=>{ }), + (3, (_, _)=>{ }), + (4, (_, _)=>{ }), + (5, (_, _)=>{ }) + }; + + public InteractionTrackerSample() + { + this.InitializeComponent(); + + var layout = new LinearLayout((id) => + new Rectangle() + { + Width = ElementWidth, + Height = ElementWidth, + Fill = new SolidColorBrush(Colors.BlueViolet), + Stroke = new SolidColorBrush(Colors.Gray), + StrokeThickness = 2 + } + , (_) => { }); + compositionCollectionView.SetLayout(layout); + compositionCollectionView.UpdateSource(elements); + } + + public class LinearLayout : Layout + { + public LinearLayout(Func elementFactory, Action log) : base(elementFactory, log) + { + } + + public LinearLayout(Layout sourceLayout) : base(sourceLayout) + { + } + + protected override void OnActivated() + { + if (TryGetBehavior>() is null) + { + // Tracker can't be created until activation, we don't have access to the root panel until then + var trackerBehavior = new InteractionTrackerBehavior(RootPanel); + AddBehavior(trackerBehavior); + + var tracker = trackerBehavior.Tracker; + var interactionSource = trackerBehavior.InteractionSource; + + UpdateTrackerLimits(); + + interactionSource.ScaleSourceMode = InteractionSourceMode.Disabled; + interactionSource.PositionXSourceMode = InteractionSourceMode.EnabledWithInertia; + interactionSource.PositionYSourceMode = InteractionSourceMode.Disabled; + } + + RootPanel.Background = new SolidColorBrush(Colors.Transparent); + RootPanel.PointerPressed += RootPointerPressed; + } + + protected override void OnDeactivated() + { + RootPanel.PointerPressed -= RootPointerPressed; + } + + void RootPointerPressed(object sender, PointerRoutedEventArgs e) + { + if (e.Pointer.PointerDeviceType == Windows.Devices.Input.PointerDeviceType.Touch) + { + var position = e.GetCurrentPoint(RootPanel); + GetBehavior>().InteractionSource.TryRedirectForManipulation(position); + } + } + + protected override void OnElementsUpdated() + { + UpdateTrackerLimits(); + } + + private void UpdateTrackerLimits() + { + var trackerBehavior = GetBehavior>(); + + var availableWidth = (float)RootPanel.ActualWidth - ElementWidth; + var elementsWidth = Elements.Count * ElementWidth * 1.2f; + + trackerBehavior.Tracker.MaxPosition = new Vector3(elementsWidth - ((float)RootPanel.ActualWidth + ElementWidth) / 2, 0, 0); + trackerBehavior.Tracker.MinPosition = new Vector3(-((float)RootPanel.ActualWidth - ElementWidth) / 2, 0, 0); + } + + private ScalarNode ScrollProgress(ElementReference element) + { + var availableWidth = RootPanelVisual.GetReference().Size.X - ElementWidth; + + return ExpressionFunctions.Clamp( + (element.Id * ElementWidth * 1.2f + - GetBehavior>().Tracker.GetReference().Position.X) / availableWidth, + 0, + 1); + } + + public override Vector3Node GetElementPositionNode(ElementReference element) + { + var availableWidth = RootPanelVisual.GetReference().Size.X - ElementWidth; + + var xPosition = availableWidth * ScrollProgress(element); + + var yPosition = 50 * ExpressionFunctions.Sin(ScrollProgress(element) * MathF.PI); + + return ExpressionFunctions.Vector3(xPosition, yPosition, 0); + } + + public override ScalarNode GetElementScaleNode(ElementReference element) => 1.5f - ExpressionFunctions.Abs(0.5f - ScrollProgress(element)); + + protected override void ConfigureElement(ElementReference element) + { + } + + public override void UpdateElement(ElementReference element) + { + } + } + } +} diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/MazeSample.xaml b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/MazeSample.xaml similarity index 100% rename from labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/MazeSample.xaml rename to labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/MazeSample.xaml diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/MazeSample.xaml.cs b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/MazeSample.xaml.cs new file mode 100644 index 000000000..05fbbf7e8 --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/MazeSample.xaml.cs @@ -0,0 +1,398 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +using CommunityToolkit.Labs.Core.SourceGenerators; +using CommunityToolkit.Labs.Core.SourceGenerators.Attributes; +using CommunityToolkit.Labs.WinUI.CompositionCollectionView; +using Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork; +using System.Numerics; + +#if !WINAPPSDK +using Windows.Foundation; +using Windows.Foundation.Collections; +using Windows.UI; +using Windows.UI.Composition; +using Windows.UI.Composition.Interactions; +using Windows.UI.StartScreen; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Controls.Primitives; +using Windows.UI.Xaml.Data; +using Windows.UI.Xaml.Hosting; +using Windows.UI.Xaml.Input; +using Windows.UI.Xaml.Media; +using Windows.UI.Xaml.Media.Imaging; +using Windows.UI.Xaml.Navigation; +using Windows.UI.Xaml.Shapes; +#else +using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Controls; +using Microsoft.UI.Xaml.Controls.Primitives; +using Microsoft.UI.Xaml.Data; +using Microsoft.UI.Xaml.Input; +using Microsoft.UI.Xaml.Media; +using Microsoft.UI.Xaml.Navigation; +#endif + + +namespace CompositionCollectionView.Sample +{ + [ToolkitSample(id: nameof(MazeSample), "Maze layout", description: "Layout driven by an interaction tracker.")] + public sealed partial class MazeSample : Page + { + enum TileType { Floor, Ceiling, HorizontalWall, VerticalWall } + + const int TileWidth = 100; + const int MazeSize = 10; + + static readonly Vector3 GoalPosition = new Vector3(900, -900, 0); + + private uint nextEntityId; + + private List<(uint, Action>)> elements { get; init; } + + public MazeSample() + { + this.InitializeComponent(); + + + List tiles = new(); + + for (int i = 0; i < MazeSize; i++) + { + for (int j = 0; j < MazeSize; j++) + { + tiles.Add(new(TileType.Floor, i, j)); + tiles.Add(new(TileType.Ceiling, i, j)); + + if (j == 0) + { + tiles.Add(new(TileType.HorizontalWall, i, j)); + } + else if (j == MazeSize - 1) + { + tiles.Add(new(TileType.HorizontalWall, i, j + 1)); + } + + if (i == 0) + { + tiles.Add(new(TileType.VerticalWall, i, j)); + } + else if (i == MazeSize - 1) + { + tiles.Add(new(TileType.VerticalWall, i + 1, j)); + } + } + } + + elements = tiles.OrderBy(x => x.Y).Select(x => CreateElement(x)).ToList(); + + var layout = new SpinningMazeLayout((id) => TileControl.Create(), (_) => { }); + compositionCollectionView.SetLayout(layout); + compositionCollectionView.UpdateSource(elements); + + Visual visual = ElementCompositionPreview.GetElementVisual(compositionCollectionView); + var viewSize = visual.GetReference().Size; + + visual.StartAnimation(AnimationConstants.TransformMatrix, + ExpressionFunctions.CreateTranslation(ExpressionFunctions.Vector3(-viewSize.X / 2, -viewSize.Y / 2, 0)) + * ExpressionFunctions.Matrix4x4( + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, -1.0f / viewSize.X, + 0.0f, 0.0f, 0.0f, 1.0f) * + ExpressionFunctions.CreateTranslation(ExpressionFunctions.Vector3(viewSize.X / 2, viewSize.Y / 2, 0))); + } + + private record Tile(TileType Type, int X, int Y); + + private (uint, Action>) CreateElement(Tile tile) + { + return (nextEntityId++, (_, dict) => + { + dict[nameof(Tile.Type)] = tile.Type; + dict[nameof(Tile.X)] = tile.X; + dict[nameof(Tile.Y)] = tile.Y; + } + ); + } + + public abstract class MazeLayout : Layout + { + protected const string PositionNode = nameof(PositionNode); + protected const string ScaleNode = nameof(ScaleNode); + protected const string RotationNode = nameof(RotationNode); + const string CameraTransformNode = nameof(CameraTransformNode); + + public MazeLayout(Func elementFactory, Action log) : base(elementFactory, log) + { + } + + public MazeLayout(Layout sourceLayout) : base(sourceLayout) + { + } + + protected override void OnActivated() + { + var translation = ExpressionFunctions.CreateTranslation(AnimatableNodes.GetOrCreateVector3Node(PositionNode, Vector3.Zero).Reference); + + var scaleNode = AnimatableNodes.GetOrCreateScalarNode(ScaleNode, 1).Reference; + var scale = ExpressionFunctions.CreateScale(ExpressionFunctions.Vector3(scaleNode, scaleNode, scaleNode)); + + var rotationNode = AnimatableNodes.GetOrCreateVector3Node(RotationNode, Vector3.Zero).Reference; + var rotation = ExpressionFunctions.CreateMatrix4x4FromAxisAngle(Vector3.UnitX, rotationNode.X) * + ExpressionFunctions.CreateMatrix4x4FromAxisAngle(Vector3.UnitY, rotationNode.Y) * + ExpressionFunctions.CreateMatrix4x4FromAxisAngle(Vector3.UnitZ, rotationNode.Z); + + AnimatableNodes.GetOrCreateMatrix4x4Node(CameraTransformNode, Matrix4x4.Identity).Animate(translation * rotation * scale); + + TileControl.LoadBrushes(); + } + + + public override Vector3Node GetElementPositionNode(ElementReference element) + { + element.Properties.TryGetValue(nameof(Tile.X), out var x); + element.Properties.TryGetValue(nameof(Tile.Y), out var y); + element.Properties.TryGetValue(nameof(Tile.Type), out var tileType); + + var xPosition = tileType switch + { + _ => (int)x! * TileWidth + }; + + var yPosition = tileType switch + { + _ => (int)y! * TileWidth + }; + + var height = tileType switch + { + TileType.Floor => TileWidth, + TileType.Ceiling => 0, + _ => 0 + }; + + var camera = AnimatableNodes.GetOrCreateMatrix4x4Node(CameraTransformNode, Matrix4x4.Identity).Reference; + + return ExpressionFunctions.Transform(ExpressionFunctions.Vector4(xPosition, height, yPosition, 1), camera).XYZ; + } + + public override ScalarNode GetElementScaleNode(ElementReference element) + { + var camera = AnimatableNodes.GetOrCreateMatrix4x4Node(CameraTransformNode, Matrix4x4.Identity).Reference; + //return camera.Channel11; + + //return RootPanelVisual.GetReference().Size.Y / TileWidth; + + //return ExpressionFunctions.Transform(ExpressionFunctions.Vector4(1, 0, 0, 0), camera).X - + // ExpressionFunctions.Transform(ExpressionFunctions.Vector4(0, 0, 0, 0), camera).X; + + return AnimatableNodes.GetOrCreateScalarNode(ScaleNode, 1).Reference; + } + + public override QuaternionNode GetElementOrientationNode(ElementReference element) + { + var localOrientation = element.Properties[nameof(Tile.Type)] switch + { + TileType.Floor => Quaternion.CreateFromYawPitchRoll(0, MathF.PI / 2, 0), + TileType.Ceiling => Quaternion.CreateFromYawPitchRoll(0, MathF.PI / 2, 0), + TileType.VerticalWall => Quaternion.CreateFromYawPitchRoll(-MathF.PI / 2, 0, 0), + TileType.HorizontalWall => Quaternion.Identity, + _ => Quaternion.Identity + }; + + var rotationNode = AnimatableNodes.GetOrCreateVector3Node(RotationNode, Vector3.Zero).Reference; + var cameraOrientation = ExpressionFunctions.CreateQuaternionFromAxisAngle(Vector3.UnitX, rotationNode.X) * + ExpressionFunctions.CreateQuaternionFromAxisAngle(Vector3.UnitY, rotationNode.Y) * + ExpressionFunctions.CreateQuaternionFromAxisAngle(Vector3.UnitZ, rotationNode.Z); + + return cameraOrientation * localOrientation; + } + + protected override void ConfigureElement(ElementReference element) + { + if (element.Container is Rectangle rect) + { + rect.Fill = TileControl.BrushFor((TileType)element.Properties[nameof(Tile.Type)]!); + } + } + + public override void UpdateElement(ElementReference element) + { + } + + protected override Transition GetElementTransitionEasingFunction(ElementReference element) => + new(600, + Window.Current.Compositor.CreateCubicBezierEasingFunction(new Vector2(0.25f, 0.1f), new Vector2(0.25f, 1f))); + } + + public class SpinningMazeLayout : MazeLayout + { + public SpinningMazeLayout(Layout sourceLayout) : base(sourceLayout) + { + } + + public SpinningMazeLayout(Func elementFactory, Action log) : base(elementFactory, log) + { + } + + protected override void OnActivated() + { + base.OnActivated(); + + var animation = Compositor.CreateVector3KeyFrameAnimation(); + animation.Duration = TimeSpan.FromSeconds(5); + animation.InsertKeyFrame(0, Vector3.Zero); + animation.InsertKeyFrame(1, new Vector3(0, MathF.PI * 2, 0)); + animation.IterationBehavior = AnimationIterationBehavior.Forever; + + var rotationNode = AnimatableNodes.GetOrCreateVector3Node(RotationNode, Vector3.Zero); + rotationNode.Animate(animation); + + float mazeSide = TileWidth * MazeSize; + var mazeCenter = new Vector3(-mazeSide / 2, 0, -mazeSide / 2); + + AnimatableNodes.GetOrCreateVector3Node(PositionNode, Vector3.Zero).Animate(ExpressionFunctions.Vector3( + ExpressionFunctions.Sin(rotationNode.Reference.Y) * mazeSide * 1.5f, + mazeSide / 5, + -ExpressionFunctions.Cos(rotationNode.Reference.Y) * mazeSide * 1.5f + ) + (Vector3Node)mazeCenter); + + AnimatableNodes.GetOrCreateScalarNode(ScaleNode, 1).Animate(RootPanelVisual.GetReference().Size.Y / TileWidth); + RootPanel.Tapped += this.OnTapped; + } + + protected override void OnDeactivated() + { + RootPanel.Tapped -= OnTapped; + } + + private void OnTapped(object sender, TappedRoutedEventArgs e) + { + TransitionTo(x => new TraversableMazeLayout(this)); + } + } + + + public class TraversableMazeLayout : MazeLayout + { + public TraversableMazeLayout(Func elementFactory, Action log) : base(elementFactory, log) + { + } + + public TraversableMazeLayout(Layout sourceLayout) : base(sourceLayout) + { + } + + protected override void OnActivated() + { + base.OnActivated(); + + var trackerBehavior = TryGetBehavior>(); + + if (trackerBehavior is null) + { + // Tracker can't be created until activation, we don't have access to the root panel until then + trackerBehavior = new InteractionTrackerBehavior(RootPanel); + AddBehavior(trackerBehavior); + } + + var tracker = trackerBehavior.Tracker; + var interactionSource = trackerBehavior.InteractionSource; + + UpdateTrackerLimits(); + + interactionSource.ScaleSourceMode = InteractionSourceMode.Disabled; + interactionSource.PositionXSourceMode = InteractionSourceMode.EnabledWithInertia; + interactionSource.PositionYSourceMode = InteractionSourceMode.EnabledWithInertia; + + AnimatableNodes.GetOrCreateVector3Node(PositionNode, Vector3.Zero).Animate( + ExpressionFunctions.Vector3( + -tracker.GetReference().Position.X, + 0, + tracker.GetReference().Position.Y)); + + trackerBehavior.TrackerOwner.OnIdleStateEntered += this.OnTrackerIdleStateEntered; + + AnimatableNodes.GetOrCreateScalarNode(ScaleNode, 1).Animate(RootPanelVisual.GetReference().Size.Y / TileWidth); + AnimatableNodes.GetOrCreateVector3Node(RotationNode, Vector3.Zero).Value = new Vector3(0, 0, 0); + + RootPanel.Background = new SolidColorBrush(Colors.Black); + RootPanel.PointerPressed += RootPointerPressed; + } + + protected override void OnDeactivated() + { + RootPanel.PointerPressed -= RootPointerPressed; + GetBehavior>().TrackerOwner.OnIdleStateEntered -= this.OnTrackerIdleStateEntered; + } + + private void OnTrackerIdleStateEntered(InteractionTracker sender, InteractionTrackerIdleStateEnteredArgs args) + { + if (Vector3.Distance(sender.Position, GoalPosition) < TileWidth) + { + TransitionTo(x => new SpinningMazeLayout(this)); + } + } + + void RootPointerPressed(object sender, PointerRoutedEventArgs e) + { + if (e.Pointer.PointerDeviceType == Windows.Devices.Input.PointerDeviceType.Touch) + { + var position = e.GetCurrentPoint(RootPanel); + GetBehavior>().InteractionSource.TryRedirectForManipulation(position); + } + } + + protected override void OnElementsUpdated() + { + UpdateTrackerLimits(); + } + + private void UpdateTrackerLimits() + { + var trackerBehavior = GetBehavior>(); + + trackerBehavior.Tracker.MaxPosition = new Vector3(TileWidth * (MazeSize - 1), 0, 0); + trackerBehavior.Tracker.MinPosition = new Vector3(0, -TileWidth * (MazeSize - 1), 0); + } + } + + private class TileControl + { + private static ImageBrush WallBrush, CeilingBrush, FloorBrush; + + public static Rectangle Create() => new Rectangle() + { + Width = TileWidth, + Height = TileWidth + }; + + public static void LoadBrushes() + { + WallBrush = WallBrush ?? new ImageBrush() + { + ImageSource = new BitmapImage(new Uri("ms-appx:///CompositionCollectionViewExperiment.Samples/Assets/wall.bmp")) + }; + + CeilingBrush = CeilingBrush ?? new ImageBrush() + { + ImageSource = new BitmapImage(new Uri("ms-appx:///CompositionCollectionViewExperiment.Samples/Assets/ceiling.bmp")) + }; + + FloorBrush = FloorBrush ?? new ImageBrush() + { + ImageSource = new BitmapImage(new Uri("ms-appx:///CompositionCollectionViewExperiment.Samples/Assets/floor.bmp")) + }; + } + + public static ImageBrush BrushFor(TileType type) => type switch + { + TileType.Ceiling => CeilingBrush, + TileType.Floor => FloorBrush, + _ => WallBrush + }; + } + } +} diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/SwitchLayoutsSample.xaml b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/SwitchLayoutsSample.xaml similarity index 100% rename from labs/CompositionCollectionView/samples/CompositionCollectionView.Sample/SwitchLayoutsSample.xaml rename to labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/SwitchLayoutsSample.xaml diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/SwitchLayoutsSample.xaml.cs b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/SwitchLayoutsSample.xaml.cs new file mode 100644 index 000000000..396641d6f --- /dev/null +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/SwitchLayoutsSample.xaml.cs @@ -0,0 +1,140 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +using CommunityToolkit.Labs.Core.SourceGenerators; +using CommunityToolkit.Labs.Core.SourceGenerators.Attributes; +using CommunityToolkit.Labs.WinUI.CompositionCollectionView; +using Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork; +using System.Numerics; + +#if !WINAPPSDK +using Windows.Foundation; +using Windows.Foundation.Collections; +using Windows.UI.Composition; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Controls.Primitives; +using Windows.UI.Xaml.Data; +using Windows.UI.Xaml.Hosting; +using Windows.UI.Xaml.Input; +using Windows.UI.Xaml.Media; +using Windows.UI.Xaml.Navigation; +using Windows.UI.Xaml.Shapes; +#else +using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Controls; +using Microsoft.UI.Xaml.Controls.Primitives; +using Microsoft.UI.Xaml.Data; +using Microsoft.UI.Xaml.Input; +using Microsoft.UI.Xaml.Media; +using Microsoft.UI.Xaml.Navigation; +#endif + + +namespace CompositionCollectionView.Sample +{ + [ToolkitSample(id: nameof(SwitchLayoutsSample), "Layout transition", description: "Transition between different layouts.")] + public sealed partial class SwitchLayoutsSample : Page + { + private List<(uint, Action>)> elements { get; init; } = new() + { + (0, (_, _)=>{ }), + (1, (_, _)=>{ }), + (2, (_, _)=>{ }), + (3, (_, _)=>{ }), + (4, (_, _)=>{ }), + (5, (_, _)=>{ }) + }; + + public SwitchLayoutsSample() + { + this.InitializeComponent(); + + var layout = new LinearLayout((id) => + new Rectangle() + { + Width = 100, + Height = 100, + Fill = new SolidColorBrush(Windows.UI.Colors.BlueViolet) + } + , (_) => { }); + compositionCollectionView.SetLayout(layout); + compositionCollectionView.UpdateSource(elements); + } + + public class LinearLayout : Layout + { + public LinearLayout(Func elementFactory, Action log) : base(elementFactory, log) + { + } + + public LinearLayout(Layout sourceLayout) : base(sourceLayout) + { + } + + public override Vector3Node GetElementPositionNode(ElementReference element) + { + return ExpressionFunctions.Vector3(element.Id * 120, 0, 0); + } + + public override ScalarNode GetElementScaleNode(ElementReference element) => 1; + + protected override void ConfigureElement(ElementReference element) + { + } + + public override void UpdateElement(ElementReference element) + { + } + + protected override Transition GetElementTransitionEasingFunction(ElementReference element) => + new(100, + Window.Current.Compositor.CreateCubicBezierEasingFunction(new Vector2(0.25f, 0.1f), new Vector2(0.25f, 1f))); + } + + public class StackLayout : Layout + { + public StackLayout(Func elementFactory, Action log) : base(elementFactory, log) + { + } + + public StackLayout(Layout sourceLayout) : base(sourceLayout) + { + } + + public override Vector3Node GetElementPositionNode(ElementReference element) + { + return ExpressionFunctions.Vector3(element.Id * 10, element.Id * 10, 0); + } + + public override ScalarNode GetElementScaleNode(ElementReference element) => (float)Math.Pow(0.95f, element.Id); + + protected override void ConfigureElement(ElementReference element) + { + } + + public override void UpdateElement(ElementReference element) + { + } + + protected override Transition GetElementTransitionEasingFunction(ElementReference element) => + new(100, + Window.Current.Compositor.CreateCubicBezierEasingFunction(new Vector2(0.25f, 0.1f), new Vector2(0.25f, 1f))); + } + + private void ToggleSwitch_Toggled(object sender, RoutedEventArgs e) + { + if (sender is ToggleSwitch toggle) + { + if (toggle.IsOn && compositionCollectionView.Layout() is LinearLayout currentLinearLayout) + { + currentLinearLayout.TransitionTo(_ => new StackLayout(currentLinearLayout)); + } + else if (!toggle.IsOn && compositionCollectionView.Layout() is StackLayout currentStackLayout) + { + currentStackLayout.TransitionTo(_ => new LinearLayout(currentStackLayout)); + } + } + } + } +} diff --git a/labs/CompositionCollectionView/src/CommunityToolkit.Labs.WinUI.CompositionCollectionView.csproj b/labs/CompositionCollectionView/src/CommunityToolkit.Labs.WinUI.CompositionCollectionView.csproj index 946826378..e9dd64a4a 100644 --- a/labs/CompositionCollectionView/src/CommunityToolkit.Labs.WinUI.CompositionCollectionView.csproj +++ b/labs/CompositionCollectionView/src/CommunityToolkit.Labs.WinUI.CompositionCollectionView.csproj @@ -23,27 +23,11 @@ True - - - - - %(Filename) - - - - - - - - - - - - - - - + + + + MSBuild:Compile diff --git a/labs/CompositionCollectionView/src/CompositionCollectionViewStyle_ClassicBinding.xaml b/labs/CompositionCollectionView/src/CompositionCollectionViewStyle_ClassicBinding.xaml deleted file mode 100644 index 053433573..000000000 --- a/labs/CompositionCollectionView/src/CompositionCollectionViewStyle_ClassicBinding.xaml +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - - - - - - - - - - - 4,4,4,4 - - - - - - - - diff --git a/labs/CompositionCollectionView/src/CompositionCollectionViewStyle_xBind.xaml b/labs/CompositionCollectionView/src/CompositionCollectionViewStyle_xBind.xaml deleted file mode 100644 index 68157a59a..000000000 --- a/labs/CompositionCollectionView/src/CompositionCollectionViewStyle_xBind.xaml +++ /dev/null @@ -1,69 +0,0 @@ - - - - - - - - - - - - - - - - 4,4,4,4 - - - - - - - - diff --git a/labs/CompositionCollectionView/src/CompositionCollectionViewStyle_xBind.xaml.cs b/labs/CompositionCollectionView/src/CompositionCollectionViewStyle_xBind.xaml.cs deleted file mode 100644 index e9d5914d5..000000000 --- a/labs/CompositionCollectionView/src/CompositionCollectionViewStyle_xBind.xaml.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace CommunityToolkit.Labs.WinUI; - -/// -/// Backing code for this resource dictionary. -/// -public sealed partial class CompositionCollectionViewStyle_xBind : ResourceDictionary -{ - // NOTICE - // This file only exists to enable x:Bind in the resource dictionary. - // Do not add code here. - // Instead, add code-behind to your templated control. - public CompositionCollectionViewStyle_xBind() - { - this.InitializeComponent(); - } -} diff --git a/labs/CompositionCollectionView/src/CompositionCollectionView_ClassicBinding.cs b/labs/CompositionCollectionView/src/CompositionCollectionView_ClassicBinding.cs deleted file mode 100644 index 41550ff53..000000000 --- a/labs/CompositionCollectionView/src/CompositionCollectionView_ClassicBinding.cs +++ /dev/null @@ -1,94 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace CommunityToolkit.Labs.WinUI; - -/// -/// An example templated control. -/// -[TemplatePart(Name = nameof(PART_HelloWorld), Type = typeof(TextBlock))] -public partial class CompositionCollectionView_ClassicBinding : Control -{ - /// - /// Creates a new instance of the class. - /// - public CompositionCollectionView_ClassicBinding() - { - this.DefaultStyleKey = typeof(CompositionCollectionView_ClassicBinding); - } - - /// - /// The primary text block that displays "Hello world". - /// - protected TextBlock? PART_HelloWorld { get; private set; } - - /// - protected override void OnApplyTemplate() - { - base.OnApplyTemplate(); - - // Detach all attached events when a new template is applied. - if (PART_HelloWorld is not null) - { - PART_HelloWorld.PointerEntered -= Element_PointerEntered; - } - - // Attach events when the template is applied and the control is loaded. - PART_HelloWorld = GetTemplateChild(nameof(PART_HelloWorld)) as TextBlock; - - if (PART_HelloWorld is not null) - { - PART_HelloWorld.PointerEntered += Element_PointerEntered; - } - } - - /// - /// The backing for the property. - /// - public static readonly DependencyProperty ItemPaddingProperty = DependencyProperty.Register( - nameof(ItemPadding), - typeof(Thickness), - typeof(CompositionCollectionView_ClassicBinding), - new PropertyMetadata(defaultValue: new Thickness(0))); - - /// - /// The backing for the property. - /// - public static readonly DependencyProperty MyPropertyProperty = DependencyProperty.Register( - nameof(MyProperty), - typeof(string), - typeof(CompositionCollectionView_ClassicBinding), - new PropertyMetadata(defaultValue: string.Empty, (d, e) => ((CompositionCollectionView_ClassicBinding)d).OnMyPropertyChanged((string)e.OldValue, (string)e.NewValue))); - - /// - /// Gets or sets an example string. A basic DependencyProperty example. - /// - public string MyProperty - { - get => (string)GetValue(MyPropertyProperty); - set => SetValue(MyPropertyProperty, value); - } - - /// - /// Gets or sets a padding for an item. A basic DependencyProperty example. - /// - public Thickness ItemPadding - { - get => (Thickness)GetValue(ItemPaddingProperty); - set => SetValue(ItemPaddingProperty, value); - } - - protected virtual void OnMyPropertyChanged(string oldValue, string newValue) - { - // Do something with the changed value. - } - - public void Element_PointerEntered(object sender, PointerRoutedEventArgs e) - { - if (sender is TextBlock text) - { - text.Opacity = 1; - } - } -} diff --git a/labs/CompositionCollectionView/src/CompositionCollectionView_xBind.cs b/labs/CompositionCollectionView/src/CompositionCollectionView_xBind.cs deleted file mode 100644 index 95bb7ee77..000000000 --- a/labs/CompositionCollectionView/src/CompositionCollectionView_xBind.cs +++ /dev/null @@ -1,71 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace CommunityToolkit.Labs.WinUI; - -/// -/// An example templated control. -/// -public partial class CompositionCollectionView_xBind: Control -{ - /// - /// Creates a new instance of the class. - /// - public CompositionCollectionView_xBind() - { - this.DefaultStyleKey = typeof(CompositionCollectionView_xBind); - - // Allows directly using this control as the x:DataType in the template. - this.DataContext = this; - } - - /// - /// The backing for the property. - /// - public static readonly DependencyProperty ItemPaddingProperty = DependencyProperty.Register( - nameof(ItemPadding), - typeof(Thickness), - typeof(CompositionCollectionView_xBind), - new PropertyMetadata(defaultValue: new Thickness(0))); - - /// - /// The backing for the property. - /// - public static readonly DependencyProperty MyPropertyProperty = DependencyProperty.Register( - nameof(MyProperty), - typeof(string), - typeof(CompositionCollectionView_xBind), - new PropertyMetadata(defaultValue: string.Empty, (d, e) => ((CompositionCollectionView_xBind)d).OnMyPropertyChanged((string)e.OldValue, (string)e.NewValue))); - - /// - /// Gets or sets an example string. A basic DependencyProperty example. - /// - public string MyProperty - { - get => (string)GetValue(MyPropertyProperty); - set => SetValue(MyPropertyProperty, value); - } - - /// - /// Gets or sets a padding for an item. A basic DependencyProperty example. - /// - public Thickness ItemPadding - { - get => (Thickness)GetValue(ItemPaddingProperty); - set => SetValue(ItemPaddingProperty, value); - } - - protected virtual void OnMyPropertyChanged(string oldValue, string newValue) - { - // Do something with the changed value. - } - - public void Element_PointerEntered(object sender, PointerRoutedEventArgs e) - { - if (sender is TextBlock text) - { - text.Opacity = 1; - } - } -} diff --git a/labs/CompositionCollectionView/src/Themes/Generic.xaml b/labs/CompositionCollectionView/src/Themes/Generic.xaml index 71a9b5550..dfb92a161 100644 --- a/labs/CompositionCollectionView/src/Themes/Generic.xaml +++ b/labs/CompositionCollectionView/src/Themes/Generic.xaml @@ -3,11 +3,6 @@ xmlns:labs="using:CommunityToolkit.Labs.WinUI" xmlns:compositioncollectionview="using:CommunityToolkit.Labs.WinUI.CompositionCollectionView"> - - - - - - + + + + diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/ExampleCompositionCollectionViewTestPage.xaml b/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/ExampleCompositionCollectionViewTestPage.xaml index 09a72853a..57231dd50 100644 --- a/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/ExampleCompositionCollectionViewTestPage.xaml +++ b/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/ExampleCompositionCollectionViewTestPage.xaml @@ -1,14 +1,14 @@ - - - - - - - + + + + + + + From 0dbd25e26f6e08bbc4df9241b4a28afed55c0b95 Mon Sep 17 00:00:00 2001 From: Arcadio Garcia Salvadores Date: Wed, 21 Sep 2022 22:14:05 -0700 Subject: [PATCH 14/44] Address PR feedback --- common/GlobalUsings_WinUI.cs | 104 +- .../Expressions/CompositionExtensions.cs | 308 ---- .../Expressions/ExpressionFunctions.cs | 1335 ----------------- .../ExpressionNodes/BooleanNode.cs | 195 --- .../Expressions/ExpressionNodes/ColorNode.cs | 138 -- .../ExpressionNodes/ExpressionNode.cs | 720 --------- .../ExpressionNodes/ExpressionNodeType.cs | 387 ----- .../ExpressionNodes/Matrix3x2Node.cs | 393 ----- .../Matrix4x4Node.Subchannel.cs | 99 -- .../ExpressionNodes/Matrix4x4Node.cs | 488 ------ .../ExpressionNodes/QuaternionNode.cs | 198 --- .../Expressions/ExpressionNodes/ScalarNode.cs | 387 ----- .../ExpressionNodes/ValueKeywordKind.cs | 22 - .../ExpressionNodes/Vector2Node.cs | 370 ----- .../ExpressionNodes/Vector3Node.cs | 404 ----- .../ExpressionNodes/Vector4Node.cs | 421 ------ .../ExpressionValues.Constant.cs | 216 --- .../ExpressionValues.CurrentValue.cs | 101 -- .../ExpressionValues.Reference.cs | 140 -- .../ExpressionValues.StartingValue.cs | 101 -- .../ExpressionValues.Target.cs | 128 -- .../Expressions/FloatExtensions.cs | 48 - .../Expressions/OperationType.cs | 47 - .../AmbientLightReferenceNode.cs | 46 - .../ReferenceNodes/ColorBrushReferenceNode.cs | 46 - .../DistantLightReferenceNode.cs | 55 - .../ReferenceNodes/DropShadowReferenceNode.cs | 73 - .../ReferenceNodes/InsetClipReferenceNode.cs | 136 -- .../InteractionTrackerReferenceNode.cs | 154 -- .../ManipulationPropertySetReferenceNode.cs | 79 - .../NineGridBrushReferenceNode.cs | 109 -- .../ReferenceNodes/PointLightReferenceNode.cs | 91 -- ...PointerPositionPropertySetReferenceNode.cs | 43 - .../PropertySetReferenceNode.cs | 52 - .../ReferenceNodes/ReferenceNode.cs | 168 --- .../ReferenceNodes/SpotLightReferenceNode.cs | 145 -- .../SurfaceBrushReferenceNode.cs | 154 -- .../ReferenceNodes/VisualReferenceNode.cs | 162 -- .../ExpressionsFork/ExpressionsFork.csproj | 189 --- .../ExpressionsFork/ExpressionsFork.nuspec | 36 - .../Properties/AssemblyInfo.cs | 29 - .../Properties/ExpressionsFork.rd.xml | 33 - .../BasicSample.xaml | 6 +- .../BasicSample.xaml.cs | 4 +- .../CanvasSample.cs | 4 +- .../CanvasSample.xaml | 6 +- .../InteractionTrackerSample.xaml | 6 +- .../InteractionTrackerSample.xaml.cs | 4 +- .../MazeSample.xaml | 6 +- .../MazeSample.xaml.cs | 10 +- .../SwitchLayoutsSample.xaml | 6 +- .../SwitchLayoutsSample.xaml.cs | 10 +- .../AnimatableCompositionNodeSet.cs | 5 +- .../AnimatableMatrix4x4CompositionNode.cs | 7 +- .../AnimatableQuaternionCompositionNode.cs | 7 +- .../AnimatableScalarCompositionNode.cs | 7 +- .../AnimatableVector3CompositionNode.cs | 7 +- .../src/AnimationConstants.cs | 5 +- .../ElementInteractionTrackerBehavior.cs | 4 +- .../Behaviors/InteractionTrackerBehavior.cs | 6 +- .../GesturePreviewControl.cs | 4 +- .../InteractionTrackerGesture.cs | 4 +- .../src/Behaviors/LayoutBehavior.cs | 12 +- .../src/BindableCompositionPropertySet.cs | 11 +- ...abs.WinUI.CompositionCollectionView.csproj | 65 - ...abs.WinUI.CompositionCollectionView.csproj | 5 +- .../src/CompositionCollectionView.cs | 52 +- .../src/DeconstructPolyfillExtensions.cs | 2 +- .../src/ElementReference.cs | 21 +- .../Expressions/CompositionExtensions.cs | 5 +- .../Expressions/ExpressionNodes/ColorNode.cs | 2 - .../ExpressionNodes/ExpressionNode.cs | 5 - .../ExpressionNodes/Matrix4x4Node.cs | 1 - .../ExpressionNodes/QuaternionNode.cs | 1 - .../Expressions/ExpressionNodes/ScalarNode.cs | 1 - .../ExpressionNodes/Vector2Node.cs | 1 - .../ExpressionNodes/Vector3Node.cs | 1 - .../ExpressionNodes/Vector4Node.cs | 1 - .../AmbientLightReferenceNode.cs | 2 - .../ReferenceNodes/ColorBrushReferenceNode.cs | 4 +- .../DistantLightReferenceNode.cs | 4 +- .../ReferenceNodes/DropShadowReferenceNode.cs | 4 +- .../ReferenceNodes/InsetClipReferenceNode.cs | 4 +- .../InteractionTrackerReferenceNode.cs | 4 +- .../ManipulationPropertySetReferenceNode.cs | 4 +- .../NineGridBrushReferenceNode.cs | 4 +- .../ReferenceNodes/PointLightReferenceNode.cs | 4 +- ...PointerPositionPropertySetReferenceNode.cs | 4 +- .../PropertySetReferenceNode.cs | 4 +- .../ReferenceNodes/ReferenceNode.cs | 5 +- .../ReferenceNodes/SpotLightReferenceNode.cs | 4 +- .../SurfaceBrushReferenceNode.cs | 4 +- .../ReferenceNodes/VisualReferenceNode.cs | 4 +- .../src/GlobalUsings_Local.cs | 2 - labs/CompositionCollectionView/src/Layout.cs | 39 +- .../src/Themes/Generic.xaml | 7 +- 96 files changed, 186 insertions(+), 8775 deletions(-) delete mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/CompositionExtensions.cs delete mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionFunctions.cs delete mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/BooleanNode.cs delete mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/ColorNode.cs delete mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/ExpressionNode.cs delete mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/ExpressionNodeType.cs delete mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Matrix3x2Node.cs delete mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Matrix4x4Node.Subchannel.cs delete mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Matrix4x4Node.cs delete mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/QuaternionNode.cs delete mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/ScalarNode.cs delete mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/ValueKeywordKind.cs delete mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Vector2Node.cs delete mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Vector3Node.cs delete mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Vector4Node.cs delete mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionValues/ExpressionValues.Constant.cs delete mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionValues/ExpressionValues.CurrentValue.cs delete mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionValues/ExpressionValues.Reference.cs delete mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionValues/ExpressionValues.StartingValue.cs delete mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionValues/ExpressionValues.Target.cs delete mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/FloatExtensions.cs delete mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/OperationType.cs delete mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/AmbientLightReferenceNode.cs delete mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/ColorBrushReferenceNode.cs delete mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/DistantLightReferenceNode.cs delete mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/DropShadowReferenceNode.cs delete mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/InsetClipReferenceNode.cs delete mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/InteractionTrackerReferenceNode.cs delete mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/ManipulationPropertySetReferenceNode.cs delete mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/NineGridBrushReferenceNode.cs delete mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/PointLightReferenceNode.cs delete mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/PointerPositionPropertySetReferenceNode.cs delete mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/PropertySetReferenceNode.cs delete mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/ReferenceNode.cs delete mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/SpotLightReferenceNode.cs delete mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/SurfaceBrushReferenceNode.cs delete mode 100644 labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/VisualReferenceNode.cs delete mode 100644 labs/CompositionCollectionView/ExpressionsFork/ExpressionsFork.csproj delete mode 100644 labs/CompositionCollectionView/ExpressionsFork/ExpressionsFork.nuspec delete mode 100644 labs/CompositionCollectionView/ExpressionsFork/Properties/AssemblyInfo.cs delete mode 100644 labs/CompositionCollectionView/ExpressionsFork/Properties/ExpressionsFork.rd.xml rename labs/CompositionCollectionView/src/{ => AnimatableNodes}/AnimatableCompositionNodeSet.cs (94%) rename labs/CompositionCollectionView/src/{ => AnimatableNodes}/AnimatableMatrix4x4CompositionNode.cs (87%) rename labs/CompositionCollectionView/src/{ => AnimatableNodes}/AnimatableQuaternionCompositionNode.cs (87%) rename labs/CompositionCollectionView/src/{ => AnimatableNodes}/AnimatableScalarCompositionNode.cs (87%) rename labs/CompositionCollectionView/src/{ => AnimatableNodes}/AnimatableVector3CompositionNode.cs (87%) delete mode 100644 labs/CompositionCollectionView/src/CommunityToolkit - Backup.Labs.WinUI.CompositionCollectionView.csproj diff --git a/common/GlobalUsings_WinUI.cs b/common/GlobalUsings_WinUI.cs index 0bfe14bd8..70e128fe2 100644 --- a/common/GlobalUsings_WinUI.cs +++ b/common/GlobalUsings_WinUI.cs @@ -1,46 +1,58 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// This file contains directives available to projects that are compiled for multiple frameworks. -// Learn more global using directives at https://docs.microsoft.com/dotnet/csharp/language-reference/keywords/using-directive#global-modifier - -global using System.Runtime.InteropServices.WindowsRuntime; - -global using CommunityToolkit.Labs.WinUI; - -global using Windows.Foundation; -global using Windows.Foundation.Collections; - -#if !WINAPPSDK -global using Windows.ApplicationModel; -global using Windows.ApplicationModel.Activation; - -global using Windows.UI.Xaml.Automation; -global using Windows.UI.Xaml.Automation.Peers; - -global using Windows.UI.Xaml; -global using Windows.UI.Xaml.Controls; -global using Windows.UI.Xaml.Controls.Primitives; -global using Windows.UI.Xaml.Data; -global using Windows.UI.Xaml.Input; -global using Windows.UI.Xaml.Markup; -global using Windows.UI.Xaml.Media; -global using Windows.UI.Xaml.Navigation; - -#else - -global using Microsoft.UI.Xaml.Automation; -global using Microsoft.UI.Xaml.Automation.Peers; - -global using Microsoft.UI.Xaml; -global using Microsoft.UI.Xaml.Controls; -global using Microsoft.UI.Xaml.Controls.Primitives; -global using Microsoft.UI.Xaml.Data; -global using Microsoft.UI.Xaml.Input; -global using Microsoft.UI.Xaml.Markup; -global using Microsoft.UI.Xaml.Media; -global using Microsoft.UI.Xaml.Navigation; -#endif - -global using MUXC = Microsoft.UI.Xaml.Controls; +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// This file contains directives available to projects that are compiled for multiple frameworks. +// Learn more global using directives at https://docs.microsoft.com/dotnet/csharp/language-reference/keywords/using-directive#global-modifier + +global using System.Runtime.InteropServices.WindowsRuntime; + +global using CommunityToolkit.Labs.WinUI; + +global using Windows.Foundation; +global using Windows.Foundation.Collections; + +#if !WINAPPSDK +global using Windows.ApplicationModel; +global using Windows.ApplicationModel.Activation; + +global using Windows.UI.Xaml.Automation; +global using Windows.UI.Xaml.Automation.Peers; + +global using Windows.UI.Xaml; +global using Windows.UI.Xaml.Controls; +global using Windows.UI.Xaml.Controls.Primitives; +global using Windows.UI.Xaml.Data; +global using Windows.UI.Xaml.Input; +global using Windows.UI.Xaml.Markup; +global using Windows.UI.Xaml.Media; +global using Windows.UI.Xaml.Navigation; + +global using Windows.UI.Composition; +global using Windows.UI.Composition.Interactions; +global using Windows.UI.Xaml.Hosting; +global using Windows.UI; + +#else + +global using Microsoft.UI.Xaml.Automation; +global using Microsoft.UI.Xaml.Automation.Peers; + +global using Microsoft.UI.Xaml; +global using Microsoft.UI.Xaml.Controls; +global using Microsoft.UI.Xaml.Controls.Primitives; +global using Microsoft.UI.Xaml.Data; +global using Microsoft.UI.Xaml.Input; +global using Microsoft.UI.Xaml.Markup; +global using Microsoft.UI.Xaml.Media; +global using Microsoft.UI.Xaml.Navigation; + +global using Microsoft.UI.Composition; +global using Microsoft.UI.Composition.Interactions; +global using Microsoft.UI.Xaml.Hosting; +global using Microsoft.UI; +global using Windows.UI; + +#endif + +global using MUXC = Microsoft.UI.Xaml.Controls; diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/CompositionExtensions.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/CompositionExtensions.cs deleted file mode 100644 index fe95b4710..000000000 --- a/labs/CompositionCollectionView/ExpressionsFork/Expressions/CompositionExtensions.cs +++ /dev/null @@ -1,308 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Windows.UI.Composition; -using Windows.UI.Composition.Interactions; - -namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork -{ - /// - /// Class CompositionExtensions. - /// - public static class CompositionExtensions - { - /// - /// Create an ExpressionNode reference to this CompositionObject. - /// - /// The comp object. - /// AmbientLightReferenceNode. - public static AmbientLightReferenceNode GetReference(this AmbientLight compObj) - { - return new AmbientLightReferenceNode(null, compObj); - } - - /// - /// Create an ExpressionNode reference to this CompositionObject. - /// - /// The comp object. - /// ColorBrushReferenceNode. - public static ColorBrushReferenceNode GetReference(this CompositionColorBrush compObj) - { - return new ColorBrushReferenceNode(null, compObj); - } - - /// - /// Create an ExpressionNode reference to this CompositionObject. - /// - /// The comp object. - /// DistantLightReferenceNode. - public static DistantLightReferenceNode GetReference(this DistantLight compObj) - { - return new DistantLightReferenceNode(null, compObj); - } - - /// - /// Create an ExpressionNode reference to this CompositionObject. - /// - /// The comp object. - /// DropShadowReferenceNode. - public static DropShadowReferenceNode GetReference(this DropShadow compObj) - { - return new DropShadowReferenceNode(null, compObj); - } - - /// - /// Create an ExpressionNode reference to this CompositionObject. - /// - /// The comp object. - /// InsetClipReferenceNode. - public static InsetClipReferenceNode GetReference(this InsetClip compObj) - { - return new InsetClipReferenceNode(null, compObj); - } - - /// - /// Create an ExpressionNode reference to this CompositionObject. - /// - /// The comp object. - /// InteractionTrackerReferenceNode. - public static InteractionTrackerReferenceNode GetReference(this InteractionTracker compObj) - { - return new InteractionTrackerReferenceNode(null, compObj); - } - - /// - /// Create an ExpressionNode reference to this CompositionObject. - /// - /// The comp object. - /// NineGridBrushReferenceNode. - public static NineGridBrushReferenceNode GetReference(this CompositionNineGridBrush compObj) - { - return new NineGridBrushReferenceNode(null, compObj); - } - - /// - /// Create an ExpressionNode reference to this CompositionObject. - /// - /// The comp object. - /// PointLightReferenceNode. - public static PointLightReferenceNode GetReference(this PointLight compObj) - { - return new PointLightReferenceNode(null, compObj); - } - - /// - /// Create an ExpressionNode reference to this CompositionObject. - /// - /// The comp object. - /// PropertySetReferenceNode. - public static PropertySetReferenceNode GetReference(this CompositionPropertySet compObj) - { - return new PropertySetReferenceNode(null, compObj); - } - - /// - /// Create an ExpressionNode reference to this CompositionObject. - /// - /// The comp object. - /// SpotLightReferenceNode. - public static SpotLightReferenceNode GetReference(this SpotLight compObj) - { - return new SpotLightReferenceNode(null, compObj); - } - - /// - /// Create an ExpressionNode reference to this CompositionObject. - /// - /// The comp object. - /// SurfaceBrushReferenceNode. - public static SurfaceBrushReferenceNode GetReference(this CompositionSurfaceBrush compObj) - { - return new SurfaceBrushReferenceNode(null, compObj); - } - - /// - /// Create an ExpressionNode reference to this CompositionObject. - /// - /// The comp object. - /// VisualReferenceNode. - public static VisualReferenceNode GetReference(this Visual compObj) - { - return new VisualReferenceNode(null, compObj); - } - - /// - /// Create an ExpressionNode reference to this specialized PropertySet. - /// - /// A class that derives from PropertySetReferenceNode. - /// The ps. - /// T. - /// Invalid property set specialization - public static T GetSpecializedReference(this CompositionPropertySet ps) - where T : PropertySetReferenceNode - { - if (typeof(T) == typeof(ManipulationPropertySetReferenceNode)) - { - return new ManipulationPropertySetReferenceNode(null, ps) as T; - } - else if (typeof(T) == typeof(PointerPositionPropertySetReferenceNode)) - { - return new PointerPositionPropertySetReferenceNode(null, ps) as T; - } - else - { - throw new System.Exception("Invalid property set specialization"); - } - } - - /// - /// Connects the specified ExpressionNode with the specified property of the object. - /// - /// The comp object. - /// The name of the property that the expression will target. - /// The root ExpressionNode that represents the ExpressionAnimation. - public static void StartAnimation(this CompositionObject compObject, string propertyName, ExpressionNode expressionNode) - { - compObject.StartAnimation(propertyName, CreateExpressionAnimationFromNode(compObject.Compositor, expressionNode)); - } - - /// - /// Inserts a KeyFrame whose value is calculated using the specified ExpressionNode. - /// - /// The keyframe animation. - /// The time the key frame should occur at, expressed as a percentage of the animation Duration. Allowed value is from 0.0 to 1.0. - /// The root ExpressionNode that represents the ExpressionAnimation. - /// The easing function to use when interpolating between frames. - public static void InsertExpressionKeyFrame(this KeyFrameAnimation keyframeAnimation, float normalizedProgressKey, ExpressionNode expressionNode, CompositionEasingFunction easing = null) - { - expressionNode.ClearReferenceInfo(); - - keyframeAnimation.InsertExpressionKeyFrame(normalizedProgressKey, expressionNode.ToExpressionString(), easing); - - expressionNode.SetAllParameters(keyframeAnimation); - } - - /// - /// Use the value of specified ExpressionNode to determine if this inertia modifier should be chosen. - /// - /// The modifier. - /// The root ExpressionNode that represents the ExpressionAnimation. - public static void SetCondition(this InteractionTrackerInertiaRestingValue modifier, ExpressionNode expressionNode) - { - modifier.Condition = CreateExpressionAnimationFromNode(modifier.Compositor, expressionNode); - } - - /// - /// Use the value of specified ExpressionNode as the resting value for this inertia modifier. - /// - /// The modifier. - /// The root ExpressionNode that represents the ExpressionAnimation. - public static void SetRestingValue(this InteractionTrackerInertiaRestingValue modifier, ExpressionNode expressionNode) - { - modifier.RestingValue = CreateExpressionAnimationFromNode(modifier.Compositor, expressionNode); - } - - /// - /// Use the value of specified ExpressionNode to determine if this inertia modifier should be chosen. - /// - /// The modifier. - /// The root ExpressionNode that represents the ExpressionAnimation. - public static void SetCondition(this InteractionTrackerInertiaMotion modifier, ExpressionNode expressionNode) - { - modifier.Condition = CreateExpressionAnimationFromNode(modifier.Compositor, expressionNode); - } - - /// - /// Use the value of specified ExpressionNode to dictate the motion for this inertia modifier. - /// - /// The modifier. - /// The root ExpressionNode that represents the ExpressionAnimation. - public static void SetMotion(this InteractionTrackerInertiaMotion modifier, ExpressionNode expressionNode) - { - modifier.Motion = CreateExpressionAnimationFromNode(modifier.Compositor, expressionNode); - } - - /// - /// Use the value of specified ExpressionNode to determine if this composition conditional value modifier should be chosen. - /// - /// The modifier. - /// The root ExpressionNode that represents the ExpressionAnimation. - public static void SetCondition(this CompositionConditionalValue modifier, ExpressionNode expressionNode) - { - modifier.Condition = CreateExpressionAnimationFromNode(modifier.Compositor, expressionNode); - } - - /// - /// Use the value of specified ExpressionNode as the value for this composition conditional value - /// - /// The modifier. - /// The root ExpressionNode that represents the ExpressionAnimation. - public static void SetValue(this CompositionConditionalValue modifier, ExpressionNode expressionNode) - { - modifier.Value = CreateExpressionAnimationFromNode(modifier.Compositor, expressionNode); - } - - /// - /// Creates the expression animation from node. - /// - /// The compositor. - /// The expression node. - /// ExpressionAnimation. - private static ExpressionAnimation CreateExpressionAnimationFromNode(Compositor compositor, ExpressionNode expressionNode) - { - // Only create a new animation if this node hasn't already generated one before, so we don't have to re-parse the expression string. - if (expressionNode.ExpressionAnimation == null) - { - expressionNode.ClearReferenceInfo(); - expressionNode.ExpressionAnimation = compositor.CreateExpressionAnimation(expressionNode.ToExpressionString()); - } - - // We need to make sure all parameters are up to date, even if the animation already existed. - expressionNode.SetAllParameters(expressionNode.ExpressionAnimation); - - return expressionNode.ExpressionAnimation; - } - - internal static float EvaluateSubchannel(this ExpressionNode node, string subchannel) => (node, subchannel) switch - { - (Vector2Node n, "X") => n.Evaluate().X, - (Vector2Node n, "Y") => n.Evaluate().Y, - - (Vector3Node n, "X") => n.Evaluate().X, - (Vector3Node n, "Y") => n.Evaluate().Y, - (Vector3Node n, "Z") => n.Evaluate().Z, - - (Vector4Node n, "X") => n.Evaluate().X, - (Vector4Node n, "Y") => n.Evaluate().Y, - (Vector4Node n, "Z") => n.Evaluate().Z, - (Vector4Node n, "W") => n.Evaluate().W, - - (Matrix3x2Node n, "Channel11") => n.Evaluate().M11, - (Matrix3x2Node n, "Channel12") => n.Evaluate().M12, - (Matrix3x2Node n, "Channel21") => n.Evaluate().M21, - (Matrix3x2Node n, "Channel22") => n.Evaluate().M22, - (Matrix3x2Node n, "Channel31") => n.Evaluate().M31, - (Matrix3x2Node n, "Channel32") => n.Evaluate().M32, - - (Matrix4x4Node n, "Channel11") => n.Evaluate().M11, - (Matrix4x4Node n, "Channel12") => n.Evaluate().M12, - (Matrix4x4Node n, "Channel13") => n.Evaluate().M13, - (Matrix4x4Node n, "Channel14") => n.Evaluate().M14, - (Matrix4x4Node n, "Channel21") => n.Evaluate().M21, - (Matrix4x4Node n, "Channel22") => n.Evaluate().M22, - (Matrix4x4Node n, "Channel23") => n.Evaluate().M23, - (Matrix4x4Node n, "Channel24") => n.Evaluate().M24, - (Matrix4x4Node n, "Channel31") => n.Evaluate().M31, - (Matrix4x4Node n, "Channel32") => n.Evaluate().M32, - (Matrix4x4Node n, "Channel33") => n.Evaluate().M33, - (Matrix4x4Node n, "Channel34") => n.Evaluate().M34, - (Matrix4x4Node n, "Channel41") => n.Evaluate().M41, - (Matrix4x4Node n, "Channel42") => n.Evaluate().M42, - (Matrix4x4Node n, "Channel43") => n.Evaluate().M43, - (Matrix4x4Node n, "Channel44") => n.Evaluate().M44, - - _ => 0 - }; - } -} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionFunctions.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionFunctions.cs deleted file mode 100644 index 205f53cd4..000000000 --- a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionFunctions.cs +++ /dev/null @@ -1,1335 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Collections.Generic; - -namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork -{ - /// - /// Class ExpressionFunctions. - /// - public static class ExpressionFunctions - { - //TODO add all of these to evaluate() - - - /// - /// Returns the angle (in radians) whose cosine is the specified number. - /// - /// Value between -1 and 1, for which to calculate the arccosine (the inverse cosine). - /// ScalarNode. - public static ScalarNode ACos(ScalarNode val) - { - return Function(ExpressionNodeType.Acos, val); - } - - /// - /// Returns the angle (in radians) whose sine is the specified number. - /// - /// Value between -1 and 1, for which to calculate the arcsine (the inverse sine). - /// ScalarNode. - public static ScalarNode ASin(ScalarNode val) - { - return Function(ExpressionNodeType.Asin, val); - } - - /// - /// Returns the angle (in radians) whose tangent is the specified number. - /// - /// Value for which to calculate the arctan (the inverse tan). - /// ScalarNode. - public static ScalarNode ATan(ScalarNode val) - { - return Function(ExpressionNodeType.Atan, val); - } - - /// - /// Returns the smallest integral value that is greater than or equal to the specified value. - /// - /// The floating point number to round. - /// ScalarNode. - public static ScalarNode Ceil(ScalarNode val) - { - return Function(ExpressionNodeType.Ceil, val); - } - - /// - /// Returns the cosine of the specified angle (in radians). - /// - /// An angle, measured in radians. - /// ScalarNode. - public static ScalarNode Cos(ScalarNode val) - { - return Function(ExpressionNodeType.Cos, val); - } - - /// - /// Returns the largest integer less than or equal to the specified value. - /// - /// The floating point number to round. - /// ScalarNode. - public static ScalarNode Floor(ScalarNode val) - { - return Function(ExpressionNodeType.Floor, val); - } - - /// - /// Returns the natural (base e) logarithm of a specified number. - /// - /// The number whose natural logarithm is to be returned. - /// ScalarNode. - public static ScalarNode Ln(ScalarNode val) - { - return Function(ExpressionNodeType.Ln, val); - } - - /// - /// Returns the base 10 logarithm of a specified number. - /// - /// The number whose base 10 logarithm is to be calculated. - /// ScalarNode. - public static ScalarNode Log10(ScalarNode val) - { - return Function(ExpressionNodeType.Log10, val); - } - - /// - /// Returns a specified number raised to the specified power. - /// - /// A floating-point number to be raised to a power. - /// A floating-point number that specifies a power. - /// ScalarNode. - public static ScalarNode Pow(ScalarNode val1, ScalarNode val2) - { - return Function(ExpressionNodeType.Pow, val1, val2); - } - - /// - /// Rounds a floating point value to the nearest integral value. - /// - /// The floating point number to round. - /// ScalarNode. - public static ScalarNode Round(ScalarNode val) - { - return Function(ExpressionNodeType.Round, val); - } - - /// - /// Returns the sine of the specified angle (in radians). - /// - /// An angle, measured in radians. - /// ScalarNode. - public static ScalarNode Sin(ScalarNode val) - { - return Function(ExpressionNodeType.Sin, val); - } - - /// - /// Returns the specified number multiplied by itself. - /// - /// The floating point number to square. - /// ScalarNode. - public static ScalarNode Square(ScalarNode val) - { - return Function(ExpressionNodeType.Square, val); - } - - /// - /// Returns the square root of a specified number. - /// - /// The number whose square root is to be returned. - /// ScalarNode. - public static ScalarNode Sqrt(ScalarNode val) - { - return Function(ExpressionNodeType.Sqrt, val); - } - - /// - /// Returns the tangent of the specified angle (in radians). - /// - /// An angle, measured in radians. - /// ScalarNode. - public static ScalarNode Tan(ScalarNode val) - { - return Function(ExpressionNodeType.Tan, val); - } - - /// - /// Converts an angle in radians to degrees as: val*180/PI. - /// - /// A floating point value that represents an angle in radians. - /// ScalarNode. - public static ScalarNode ToDegrees(ScalarNode val) - { - return Function(ExpressionNodeType.ToDegrees, val); - } - - /// - /// Converts an angle in degrees to radians as: val*PI/180. - /// - /// A floating point value that represents an angle in degrees. - /// ScalarNode. - public static ScalarNode ToRadians(ScalarNode val) - { - return Function(ExpressionNodeType.ToRadians, val); - } - - // System.Numerics functions - - /// - /// Returns the absolute value of the specified input. For vectors, the absolute value of each subchannel is returned. - /// - /// The input value. - /// ScalarNode. - public static ScalarNode Abs(ScalarNode val) - { - return Function(ExpressionNodeType.Absolute, val); - } - - /// - /// Returns the absolute value of the specified input. For vectors, the absolute value of each subchannel is returned. - /// - /// The input value. - /// Vector2Node. - public static Vector2Node Abs(Vector2Node val) - { - return Function(ExpressionNodeType.Absolute, val); - } - - /// - /// Returns the absolute value of the specified input. For vectors, the absolute value of each subchannel is returned. - /// - /// The input value. - /// Vector3Node. - public static Vector3Node Abs(Vector3Node val) - { - return Function(ExpressionNodeType.Absolute, val); - } - - /// - /// Returns the absolute value of the specified input. For vectors, the absolute value of each subchannel is returned. - /// . - /// - /// The input value. - /// Vector4Node. - public static Vector4Node Abs(Vector4Node val) - { - return Function(ExpressionNodeType.Absolute, val); - } - - /// - /// Restricts a value to be within a specified range. For vectors, each subchannel is clamped. - /// - /// The value to clamp. - /// The specified minimum range. - /// The specified maximum range. - /// ScalarNode. - public static ScalarNode Clamp(ScalarNode val, ScalarNode min, ScalarNode max) - { - return Function(ExpressionNodeType.Clamp, val, min, max); - } - - /// - /// Restricts a value to be within a specified range. For vectors, each subchannel is clamped. - /// - /// The value to clamp. - /// The specified minimum range. - /// The specified maximum range. - /// Vector2Node. - public static Vector2Node Clamp(Vector2Node val, Vector2Node min, Vector2Node max) - { - return Function(ExpressionNodeType.Clamp, val, min, max); - } - - /// - /// Restricts a value to be within a specified range. For vectors, each subchannel is clamped. - /// - /// The value to clamp. - /// The specified minimum range. - /// The specified maximum range. - /// Vector3Node. - public static Vector3Node Clamp(Vector3Node val, Vector3Node min, Vector3Node max) - { - return Function(ExpressionNodeType.Clamp, val, min, max); - } - - /// - /// Restricts a value to be within a specified range. For vectors, each subchannel is clamped. - /// - /// The value to clamp. - /// The specified minimum range. - /// The specified maximum range. - /// Vector4Node. - public static Vector4Node Clamp(Vector4Node val, Vector4Node min, Vector4Node max) - { - return Function(ExpressionNodeType.Clamp, val, min, max); - } - - /// - /// Linearly interpolates between two colors in the default color space. - /// - /// Color source value 1. - /// Color source value 2. - /// A value between 0 and 1.0 indicating the weight of val2. - /// ColorNode. - public static ColorNode ColorLerp(ColorNode val1, ColorNode val2, ScalarNode progress) - { - return Function(ExpressionNodeType.ColorLerp, val1, val2, progress); - } - - /// - /// Linearly interpolates between two colors in the HSL color space. - /// - /// Color source value 1. - /// Color source value 2. - /// A value between 0 and 1.0 indicating the weight of val2. - /// ColorNode. - public static ColorNode ColorLerpHsl(ColorNode val1, ColorNode val2, ScalarNode progress) - { - return Function(ExpressionNodeType.ColorLerpHsl, val1, val2, progress); - } - - /// - /// Linearly interpolates between two colors in the RBG color space. - /// - /// Color source value 1. - /// Color source value 2. - /// A value between 0 and 1.0 indicating the weight of val2. - /// ColorNode. - public static ColorNode ColorLerpRgb(ColorNode val1, ColorNode val2, ScalarNode progress) - { - return Function(ExpressionNodeType.ColorLerpRgb, val1, val2, progress); - } - - /// - /// Concatenates two Quaternions; the result represents the first rotation followed by the second rotation. - /// - /// The first quaternion rotation in the series. - /// The second quaternion rotation in the series. - /// QuaternionNode. - public static QuaternionNode Concatenate(QuaternionNode val1, QuaternionNode val2) - { - return Function(ExpressionNodeType.Concatenate, val1, val2); - } - - /// - /// Returns the distance between two vectors as: sqrt((x1-x2)^2 + (y1-y2)^2 + ...). - /// - /// Source value 1. - /// Source value 2. - /// ScalarNode. - public static ScalarNode Distance(ScalarNode val1, ScalarNode val2) - { - return Function(ExpressionNodeType.Distance, val1, val2); - } - - /// - /// Returns the distance between two vectors as: sqrt((x1-x2)^2 + (y1-y2)^2 + ...). - /// - /// Source value 1. - /// Source value 2. - /// ScalarNode. - public static ScalarNode Distance(Vector2Node val1, Vector2Node val2) - { - return Function(ExpressionNodeType.Distance, val1, val2); - } - - /// - /// Returns the distance between two vectors as: sqrt((x1-x2)^2 + (y1-y2)^2 + ...). - /// - /// Source value 1. - /// Source value 2. - /// ScalarNode. - public static ScalarNode Distance(Vector3Node val1, Vector3Node val2) - { - return Function(ExpressionNodeType.Distance, val1, val2); - } - - /// - /// Returns the distance between two vectors as: sqrt((x1-x2)^2 + (y1-y2)^2 + ...). - /// - /// Source value 1. - /// Source value 2. - /// ScalarNode. - public static ScalarNode Distance(Vector4Node val1, Vector4Node val2) - { - return Function(ExpressionNodeType.Distance, val1, val2); - } - - /// - /// Returns the squared distance between two vectors as: ((x1-x2)^2 + (y1-y2)^2 + ...). - /// - /// Source value 1. - /// Source value 2. - /// ScalarNode. - public static ScalarNode DistanceSquared(ScalarNode val1, ScalarNode val2) - { - return Function(ExpressionNodeType.DistanceSquared, val1, val2); - } - - /// - /// Returns the squared distance between two vectors as: ((x1-x2)^2 + (y1-y2)^2 + ...). - /// - /// Source value 1. - /// Source value 2. - /// ScalarNode. - public static ScalarNode DistanceSquared(Vector2Node val1, Vector2Node val2) - { - return Function(ExpressionNodeType.DistanceSquared, val1, val2); - } - - /// - /// Returns the squared distance between two vectors as: ((x1-x2)^2 + (y1-y2)^2 + ...). - /// - /// Source value 1. - /// Source value 2. - /// ScalarNode. - public static ScalarNode DistanceSquared(Vector3Node val1, Vector3Node val2) - { - return Function(ExpressionNodeType.DistanceSquared, val1, val2); - } - - /// - /// Returns the squared distance between two vectors as: ((x1-x2)^2 + (y1-y2)^2 + ...). - /// - /// Source value 1. - /// Source value 2. - /// ScalarNode. - public static ScalarNode DistanceSquared(Vector4Node val1, Vector4Node val2) - { - return Function(ExpressionNodeType.DistanceSquared, val1, val2); - } - - /// - /// Returns the inverse of the specified matrix. - /// - /// The matrix to invert. - /// Matrix3x2Node. - public static Matrix3x2Node Inverse(Matrix3x2Node val) - { - return Function(ExpressionNodeType.Inverse, val); - } - - /// - /// Returns the inverse of the specified matrix. - /// - /// The matrix to invert. - /// Matrix4x4Node. - public static Matrix4x4Node Inverse(Matrix4x4Node val) - { - return Function(ExpressionNodeType.Inverse, val); - } - - /// - /// Returns the length of the vector as: sqrt(x^2 + y^2 + ...). - /// - /// Vector value to return the length of. - /// ScalarNode. - public static ScalarNode Length(ScalarNode val) - { - return Function(ExpressionNodeType.Length, val); - } - - /// - /// Returns the length of the vector as: sqrt(x^2 + y^2 + ...). - /// - /// Vector value to return the length of. - /// ScalarNode. - public static ScalarNode Length(Vector2Node val) - { - return Function(ExpressionNodeType.Length, val); - } - - /// - /// Returns the length of the vector as: sqrt(x^2 + y^2 + ...). - /// - /// Vector value to return the length of. - /// ScalarNode. - public static ScalarNode Length(Vector3Node val) - { - return Function(ExpressionNodeType.Length, val); - } - - /// - /// Returns the length of the vector as: sqrt(x^2 + y^2 + ...). - /// - /// Vector value to return the length of. - /// ScalarNode. - public static ScalarNode Length(Vector4Node val) - { - return Function(ExpressionNodeType.Length, val); - } - - /// - /// Returns the length of the vector as: sqrt(x^2 + y^2 + ...). - /// - /// Vector value to return the length of. - /// ScalarNode. - public static ScalarNode Length(QuaternionNode val) - { - return Function(ExpressionNodeType.Length, val); - } - - /// - /// Returns the squared length of the vector as: (x^2 + y^2 + ...). - /// - /// Vector value to return the length squared of. - /// ScalarNode. - public static ScalarNode LengthSquared(ScalarNode val) - { - return Function(ExpressionNodeType.LengthSquared, val); - } - - /// - /// Returns the squared length of the vector as: (x^2 + y^2 + ...). - /// - /// Vector value to return the length squared of. - /// ScalarNode. - public static ScalarNode LengthSquared(Vector2Node val) - { - return Function(ExpressionNodeType.LengthSquared, val); - } - - /// - /// Returns the squared length of the vector as: (x^2 + y^2 + ...). - /// - /// Vector value to return the length squared of. - /// ScalarNode. - public static ScalarNode LengthSquared(Vector3Node val) - { - return Function(ExpressionNodeType.LengthSquared, val); - } - - /// - /// Returns the squared length of the vector as: (x^2 + y^2 + ...). - /// - /// Vector value to return the length squared of. - /// ScalarNode. - public static ScalarNode LengthSquared(Vector4Node val) - { - return Function(ExpressionNodeType.LengthSquared, val); - } - - /// - /// Returns the squared length of the vector as: (x^2 + y^2 + ...). - /// - /// Vector value to return the length squared of. - /// ScalarNode. - public static ScalarNode LengthSquared(QuaternionNode val) - { - return Function(ExpressionNodeType.LengthSquared, val); - } - - /// - /// Linearly interpolates between two vectors as: Output.x = x1 + (x2-x1)*progress. - /// - /// Source value 1. - /// Source value 2. - /// A value between 0 and 1.0 indicating the weight of val2. - /// ScalarNode. - public static ScalarNode Lerp(ScalarNode val1, ScalarNode val2, ScalarNode progress) - { - return Function(ExpressionNodeType.Lerp, val1, val2, progress); - } - - /// - /// Linearly interpolates between two vectors as: Output.x = x1 + (x2-x1)*progress. - /// - /// Source value 1. - /// Source value 2. - /// A value between 0 and 1.0 indicating the weight of val2. - /// Vector2Node. - public static Vector2Node Lerp(Vector2Node val1, Vector2Node val2, ScalarNode progress) - { - return Function(ExpressionNodeType.Lerp, val1, val2, progress); - } - - /// - /// Linearly interpolates between two vectors as: Output.x = x1 + (x2-x1)*progress. - /// - /// Source value 1. - /// Source value 2. - /// A value between 0 and 1.0 indicating the weight of val2. - /// Vector3Node. - public static Vector3Node Lerp(Vector3Node val1, Vector3Node val2, ScalarNode progress) - { - return Function(ExpressionNodeType.Lerp, val1, val2, progress); - } - - /// - /// Linearly interpolates between two vectors as: Output.x = x1 + (x2-x1)*progress. - /// - /// Source value 1. - /// Source value 2. - /// A value between 0 and 1.0 indicating the weight of val2. - /// Vector4Node. - public static Vector4Node Lerp(Vector4Node val1, Vector4Node val2, ScalarNode progress) - { - return Function(ExpressionNodeType.Lerp, val1, val2, progress); - } - - /// - /// Returns the maximum of two values. For vectors, the max of each subchannel is returned. - /// - /// Source value 1. - /// Source value 2. - /// ScalarNode. - public static ScalarNode Max(ScalarNode val1, ScalarNode val2) - { - return Function(ExpressionNodeType.Max, val1, val2); - } - - /// - /// Returns the maximum of two values. For vectors, the max of each subchannel is returned. - /// - /// Source value 1. - /// Source value 2. - /// Vector2Node. - public static Vector2Node Max(Vector2Node val1, Vector2Node val2) - { - return Function(ExpressionNodeType.Max, val1, val2); - } - - /// - /// Returns the maximum of two values. For vectors, the max of each subchannel is returned. - /// - /// Source value 1. - /// Source value 2. - /// Vector3Node. - public static Vector3Node Max(Vector3Node val1, Vector3Node val2) - { - return Function(ExpressionNodeType.Max, val1, val2); - } - - /// - /// Returns the maximum of two values. For vectors, the max of each subchannel is returned. - /// - /// Source value 1. - /// Source value 2. - /// Vector4Node. - public static Vector4Node Max(Vector4Node val1, Vector4Node val2) - { - return Function(ExpressionNodeType.Max, val1, val2); - } - - /// - /// Returns the minimum of two values. For vectors, the min of each subchannel is returned. - /// - /// Source value 1. - /// Source value 2. - /// ScalarNode. - public static ScalarNode Min(ScalarNode val1, ScalarNode val2) - { - return Function(ExpressionNodeType.Min, val1, val2); - } - - /// - /// Returns the minimum of two values. For vectors, the min of each subchannel is returned. - /// - /// Source value 1. - /// Source value 2. - /// Vector2Node. - public static Vector2Node Min(Vector2Node val1, Vector2Node val2) - { - return Function(ExpressionNodeType.Min, val1, val2); - } - - /// - /// Returns the minimum of two values. For vectors, the min of each subchannel is returned. - /// - /// Source value 1. - /// Source value 2. - /// Vector3Node. - public static Vector3Node Min(Vector3Node val1, Vector3Node val2) - { - return Function(ExpressionNodeType.Min, val1, val2); - } - - /// - /// Returns the minimum of two values. For vectors, the min of each subchannel is returned. - /// - /// Source value 1. - /// Source value 2. - /// Vector4Node. - public static Vector4Node Min(Vector4Node val1, Vector4Node val2) - { - return Function(ExpressionNodeType.Min, val1, val2); - } - - /// - /// Returns the remainder resulting from dividing val1/val2. For vectors, the remainder for each subchannel is returned. - /// - /// The numerator value. - /// The denominator value. - /// ScalarNode. - public static ScalarNode Mod(ScalarNode val1, ScalarNode val2) - { - return Function(ExpressionNodeType.Modulus, val1, val2); - } - - /// - /// Returns the remainder resulting from dividing val1/val2. For vectors, the remainder for each subchannel is returned. - /// - /// The numerator value. - /// The denominator value. - /// Vector2Node. - public static Vector2Node Mod(Vector2Node val1, Vector2Node val2) - { - return Function(ExpressionNodeType.Modulus, val1, val2); - } - - /// - /// Returns the remainder resulting from dividing val1/val2. For vectors, the remainder for each subchannel is returned. - /// - /// The numerator value. - /// The denominator value. - /// Vector3Node. - public static Vector3Node Mod(Vector3Node val1, Vector3Node val2) - { - return Function(ExpressionNodeType.Modulus, val1, val2); - } - - /// - /// Returns the remainder resulting from dividing val1/val2. For vectors, the remainder for each subchannel is returned. - /// - /// The numerator value. - /// The denominator value. - /// Vector4Node. - public static Vector4Node Mod(Vector4Node val1, Vector4Node val2) - { - return Function(ExpressionNodeType.Modulus, val1, val2); - } - - /// - /// Returns the normalized version of a vector. - /// - /// Vector value to normalize. - /// Vector2Node. - public static Vector2Node Normalize(Vector2Node val) - { - return Function(ExpressionNodeType.Normalize, val); - } - - /// - /// Returns the normalized version of a vector. - /// - /// Vector value to normalize. - /// Vector3Node. - public static Vector3Node Normalize(Vector3Node val) - { - return Function(ExpressionNodeType.Normalize, val); - } - - /// - /// Returns the normalized version of a vector. - /// - /// Vector value to normalize. - /// Vector4Node. - public static Vector4Node Normalize(Vector4Node val) - { - return Function(ExpressionNodeType.Normalize, val); - } - - /// - /// Returns the normalized version of a vector. - /// - /// Vector value to normalize. - /// QuaternionNode. - public static QuaternionNode Normalize(QuaternionNode val) - { - return Function(ExpressionNodeType.Normalize, val); - } - - /// - /// Multiply each subchannel of the specified vector/matrix by a float value. - /// - /// Source value to scale. - /// Scaling value. - /// ScalarNode. - public static ScalarNode Scale(ScalarNode val1, ScalarNode val2) - { - return Function(ExpressionNodeType.Scale, val1, val2); - } - - /// - /// Multiply each subchannel of the specified vector/matrix by a float value. - /// - /// Source value to scale. - /// Scaling value. - /// Vector2Node. - public static Vector2Node Scale(Vector2Node val1, ScalarNode val2) - { - return Function(ExpressionNodeType.Scale, val1, val2); - } - - /// - /// Multiply each subchannel of the specified vector/matrix by a float value. - /// - /// Source value to scale. - /// Scaling value. - /// Vector3Node. - public static Vector3Node Scale(Vector3Node val1, ScalarNode val2) - { - return Function(ExpressionNodeType.Scale, val1, val2); - } - - /// - /// Multiply each subchannel of the specified vector/matrix by a float value. - /// - /// Source value to scale. - /// Scaling value. - /// Vector4Node. - public static Vector4Node Scale(Vector4Node val1, ScalarNode val2) - { - return Function(ExpressionNodeType.Scale, val1, val2); - } - - /// - /// Multiply each subchannel of the specified vector/matrix by a float value. - /// - /// Source value to scale. - /// Scaling value. - /// Matrix3x2Node. - public static Matrix3x2Node Scale(Matrix3x2Node val1, ScalarNode val2) - { - return Function(ExpressionNodeType.Scale, val1, val2); - } - - /// - /// Multiply each subchannel of the specified vector/matrix by a float value. - /// - /// Source value to scale. - /// Scaling value. - /// Matrix4x4Node. - public static Matrix4x4Node Scale(Matrix4x4Node val1, ScalarNode val2) - { - return Function(ExpressionNodeType.Scale, val1, val2); - } - - /// - /// Spherically interpolates between two quaternions. - /// - /// Quaternion source value 1. - /// Quaternion source value 2. - /// A value between 0 and 1.0 indicating the weight of val2. - /// QuaternionNode. - public static QuaternionNode Slerp(QuaternionNode val1, QuaternionNode val2, ScalarNode progress) - { - return Function(ExpressionNodeType.Slerp, val1, val2, progress); - } - - /// - /// Transforms a vector by the specified matrix. - /// - /// Vector to be transformed. - /// The transformation matrix. - /// Vector2Node. - public static Vector2Node Transform(Vector2Node val1, Matrix3x2Node val2) - { - return Function(ExpressionNodeType.Transform, val1, val2); - } - - /// - /// Transforms a vector by the specified matrix. - /// - /// Vector to be transformed. - /// The transformation matrix. - /// Vector4Node. - public static Vector4Node Transform(Vector4Node val1, Matrix4x4Node val2) - { - return Function(ExpressionNodeType.Transform, val1, val2); - } - - // System.Numerics Type Constructors - - /// - /// Creates a vector whose subchannels have the specified values. - /// - /// The x. - /// The y. - /// Vector2Node. - public static Vector2Node Vector2(ScalarNode x, ScalarNode y) - { - return Function(ExpressionNodeType.Vector2, x, y); - } - - /// - /// Creates a vector whose subchannels have the specified values. - /// - /// The x. - /// The y. - /// The z. - /// Vector3Node. - public static Vector3Node Vector3(ScalarNode x, ScalarNode y, ScalarNode z) - { - return Function(ExpressionNodeType.Vector3, x, y, z); - } - - /// - /// Creates a vector whose subchannels have the specified values. - /// - /// The x. - /// The y. - /// The z. - /// The w. - /// Vector4Node. - public static Vector4Node Vector4(ScalarNode x, ScalarNode y, ScalarNode z, ScalarNode w) - { - return Function(ExpressionNodeType.Vector4, x, y, z, w); - } - - /// - /// Creates a color in the HSL format. - /// - /// Hue - /// Saturation - /// Luminosity - /// ColorNode. - public static ColorNode ColorHsl(ScalarNode h, ScalarNode s, ScalarNode l) - { - return Function(ExpressionNodeType.ColorHsl, h, s, l); - } - - /// - /// Creates a Color in the ARGB format. - /// - /// The alpha. - /// The red. - /// The green. - /// The blue. - /// ColorNode. - public static ColorNode ColorRgb(ScalarNode alpha, ScalarNode red, ScalarNode green, ScalarNode blue) - { - return Function(ExpressionNodeType.ColorRgb, alpha, red, green, blue); - } - - /// - /// Creates a quaternion whose subchannels have the specified values. - /// - /// The x. - /// The y. - /// The z. - /// The w. - /// QuaternionNode. - public static QuaternionNode Quaternion(ScalarNode x, ScalarNode y, ScalarNode z, ScalarNode w) - { - return Function(ExpressionNodeType.Quaternion, x, y, z, w); - } - - /// - /// Creates a matrix whose subchannels have the specified values. - /// - /// The channel11. - /// The channel12. - /// The channel21. - /// The channel22. - /// The channel31. - /// The channel32. - /// Matrix3x2Node. - public static Matrix3x2Node Matrix3x2(ScalarNode channel11, ScalarNode channel12, ScalarNode channel21, ScalarNode channel22, ScalarNode channel31, ScalarNode channel32) - { - return Function(ExpressionNodeType.Matrix3x2, channel11, channel12, channel21, channel22, channel31, channel32); - } - - /// - /// Creates a matrix whose subchannels have the specified values. - /// - /// The channel11. - /// The channel12. - /// The channel13. - /// The channel14. - /// The channel21. - /// The channel22. - /// The channel23. - /// The channel24. - /// The channel31. - /// The channel32. - /// The channel33. - /// The channel34. - /// The channel41. - /// The channel42. - /// The channel43. - /// The channel44. - /// Matrix4x4Node. -#pragma warning disable SA1117 // Parameters must be on same line or separate lines - public static Matrix4x4Node Matrix4x4(ScalarNode channel11, ScalarNode channel12, ScalarNode channel13, ScalarNode channel14, - ScalarNode channel21, ScalarNode channel22, ScalarNode channel23, ScalarNode channel24, - ScalarNode channel31, ScalarNode channel32, ScalarNode channel33, ScalarNode channel34, - ScalarNode channel41, ScalarNode channel42, ScalarNode channel43, ScalarNode channel44) -#pragma warning restore SA1117 // Parameters must be on same line or separate lines - { - return Function(ExpressionNodeType.Matrix4x4, channel11, channel12, channel13, channel14, channel21, channel22, channel23, channel24, channel31, channel32, channel33, channel34, channel41, channel42, channel43, channel44); - } - - /// - /// Creates a 4x4 matrix from a 3x2 matrix. - /// - /// The value. - /// Matrix4x4Node. - public static Matrix4x4Node Matrix4x4(Matrix3x2Node val) - { -#pragma warning disable SA1117 // Parameters must be on same line or separate lines - return Function( - ExpressionNodeType.Matrix4x4, - val.Channel11, val.Channel12, (ScalarNode)0, (ScalarNode)0, - val.Channel21, val.Channel22, (ScalarNode)0, (ScalarNode)0, - (ScalarNode)0, (ScalarNode)0, (ScalarNode)1, (ScalarNode)0, - val.Channel31, val.Channel32, (ScalarNode)0, (ScalarNode)1); -#pragma warning restore SA1117 // Parameters must be on same line or separate lines - } - - /// - /// Creates a translation matrix from the specified vector. - /// - /// Source translation vector. - /// Matrix3x2Node. - public static Matrix3x2Node CreateTranslation(Vector2Node val) - { - return Function(ExpressionNodeType.Matrix3x2FromTranslation, val); - } - - /// - /// Creates a translation matrix from the specified vector. - /// - /// Source translation vector. - /// Matrix4x4Node. - public static Matrix4x4Node CreateTranslation(Vector3Node val) - { - return Function(ExpressionNodeType.Matrix4x4FromTranslation, val); - } - - /// - /// Creates a scale matrix from the specified vector scale. - /// - /// Source scaling vector. - /// Matrix3x2Node. - public static Matrix3x2Node CreateScale(Vector2Node val) - { - return Function(ExpressionNodeType.Matrix3x2FromScale, val); - } - - /// - /// Creates a scale matrix from the specified vector scale. - /// - /// Source scaling vector. - /// Matrix4x4Node. - public static Matrix4x4Node CreateScale(Vector3Node val) - { - return Function(ExpressionNodeType.Matrix4x4FromScale, val); - } - - /// - /// Creates a skew matrix from the specified angles in radians. - /// - /// X angle, in radians. - /// Y angle, in radians. - /// The centerpoint for the operation. - /// Matrix3x2Node. - public static Matrix3x2Node CreateSkew(ScalarNode xAngle, ScalarNode yAngle, Vector2Node centerPoint) - { - return Function(ExpressionNodeType.Matrix3x2FromSkew, xAngle, yAngle, centerPoint); - } - - /// - /// Creates a rotation matrix using the given rotation in radians. - /// - /// Angle, in radians. - /// Matrix3x2Node. - public static Matrix3x2Node CreateRotation(ScalarNode angle) - { - return Function(ExpressionNodeType.Matrix3x2FromRotation, angle); - } - - /// - /// Creates a matrix that rotates around an arbitrary vector. - /// - /// Rotation axis - /// Angle, in radians. - /// Matrix4x4Node. - public static Matrix4x4Node CreateMatrix4x4FromAxisAngle(Vector3Node axis, ScalarNode angle) - { - return Function(ExpressionNodeType.Matrix4x4FromAxisAngle, axis, angle); - } - - /// - /// Creates a quaternion that rotates around an arbitrary vector. - /// - /// Rotation axis - /// Angle, in radians. - /// QuaternionNode. - public static QuaternionNode CreateQuaternionFromAxisAngle(Vector3Node axis, ScalarNode angle) - { - return Function(ExpressionNodeType.QuaternionFromAxisAngle, axis, angle); - } - - /// - /// Performs a logical AND operation on two boolean values as: val1 && val2. - /// - /// The val1. - /// The val2. - /// BooleanNode. - public static BooleanNode And(BooleanNode val1, BooleanNode val2) - { - return Function(ExpressionNodeType.And, val1, val2); - } - - /// - /// Performs a logical OR operation on two boolean values as: val1 || val2. - /// - /// The val1. - /// The val2. - /// BooleanNode. - public static BooleanNode Or(BooleanNode val1, BooleanNode val2) - { - return Function(ExpressionNodeType.Or, val1, val2); - } - - /// - /// Performs a logical NOT operation on a specified boolean value as: !val. - /// - /// The value. - /// BooleanNode. - public static BooleanNode Not(BooleanNode val) - { - return Function(ExpressionNodeType.Not, val); - } - - /// - /// Returns one of two values, depending on the value of the boolean condition. - /// - /// Boolean value used to determine whether to return the value represented by 'trueCase' or 'falseCase'. - /// Value to return if 'condition' evaluates to true. - /// Value to return if 'condition' evaluates to false. - /// ScalarNode. - public static ScalarNode Conditional(BooleanNode condition, ScalarNode trueCase, ScalarNode falseCase) - { - return Function(ExpressionNodeType.Conditional, condition, trueCase, falseCase); - } - - /// - /// Returns one of two values, depending on the value of the boolean condition. - /// - /// Boolean value used to determine whether to return the value represented by 'trueCase' or 'falseCase'. - /// Value to return if 'condition' evaluates to true. - /// Value to return if 'condition' evaluates to false. - /// Vector2Node. - public static Vector2Node Conditional(BooleanNode condition, Vector2Node trueCase, Vector2Node falseCase) - { - return Function(ExpressionNodeType.Conditional, condition, trueCase, falseCase); - } - - /// - /// Returns one of two values, depending on the value of the boolean condition. - /// - /// Boolean value used to determine whether to return the value represented by 'trueCase' or 'falseCase'. - /// Value to return if 'condition' evaluates to true. - /// Value to return if 'condition' evaluates to false. - /// Vector3Node. - public static Vector3Node Conditional(BooleanNode condition, Vector3Node trueCase, Vector3Node falseCase) - { - return Function(ExpressionNodeType.Conditional, condition, trueCase, falseCase); - } - - /// - /// Returns one of two values, depending on the value of the boolean condition. - /// - /// Boolean value used to determine whether to return the value represented by 'trueCase' or 'falseCase'. - /// Value to return if 'condition' evaluates to true. - /// Value to return if 'condition' evaluates to false. - /// Vector4Node. - public static Vector4Node Conditional(BooleanNode condition, Vector4Node trueCase, Vector4Node falseCase) - { - return Function(ExpressionNodeType.Conditional, condition, trueCase, falseCase); - } - - /// - /// Returns one of two values, depending on the value of the boolean condition. - /// - /// Boolean value used to determine whether to return the value represented by 'trueCase' or 'falseCase'. - /// Value to return if 'condition' evaluates to true. - /// Value to return if 'condition' evaluates to false. - /// ColorNode. - public static ColorNode Conditional(BooleanNode condition, ColorNode trueCase, ColorNode falseCase) - { - return Function(ExpressionNodeType.Conditional, condition, trueCase, falseCase); - } - - /// - /// Returns one of two values, depending on the value of the boolean condition. - /// - /// Boolean value used to determine whether to return the value represented by 'trueCase' or 'falseCase'. - /// Value to return if 'condition' evaluates to true. - /// Value to return if 'condition' evaluates to false. - /// QuaternionNode. - public static QuaternionNode Conditional(BooleanNode condition, QuaternionNode trueCase, QuaternionNode falseCase) - { - return Function(ExpressionNodeType.Conditional, condition, trueCase, falseCase); - } - - /// - /// Returns one of two values, depending on the value of the boolean condition. - /// - /// Boolean value used to determine whether to return the value represented by 'trueCase' or 'falseCase'. - /// Value to return if 'condition' evaluates to true. - /// Value to return if 'condition' evaluates to false. - /// Matrix3x2Node. - public static Matrix3x2Node Conditional(BooleanNode condition, Matrix3x2Node trueCase, Matrix3x2Node falseCase) - { - return Function(ExpressionNodeType.Conditional, condition, trueCase, falseCase); - } - - /// - /// Returns one of two values, depending on the value of the boolean condition. - /// - /// Boolean value used to determine whether to return the value represented by 'trueCase' or 'falseCase'. - /// Value to return if 'condition' evaluates to true. - /// Value to return if 'condition' evaluates to false. - /// Matrix4x4Node. - public static Matrix4x4Node Conditional(BooleanNode condition, Matrix4x4Node trueCase, Matrix4x4Node falseCase) - { - return Function(ExpressionNodeType.Conditional, condition, trueCase, falseCase); - } - - /// - /// Functions the specified node type. - /// - /// A class that derives from ExpressionNode. - /// Type of the node. - /// The expression function parameters. - /// T. - internal static T Function(ExpressionNodeType nodeType, params ExpressionNode[] expressionFunctionParams) - where T : ExpressionNode - { - T newNode = ExpressionNode.CreateExpressionNode(); - - (newNode as ExpressionNode).NodeType = nodeType; - foreach (var param in expressionFunctionParams) - { - (newNode as ExpressionNode).Children.Add(param); - } - - return newNode; - } - - /// - /// Gets the type of the node information from. - /// - /// The type. - /// ExpressionNodeInfo. - internal static ExpressionNodeInfo GetNodeInfoFromType(ExpressionNodeType type) - { - return _expressionNodeInfo[type]; - } - - /// - /// Struct ExpressionNodeInfo - /// - internal struct ExpressionNodeInfo - { - /// - /// Initializes a new instance of the struct. - /// - /// Kind of the node operation. - /// The operation string. - public ExpressionNodeInfo(OperationType nodeOperationKind, string operationString) - { - NodeOperationKind = nodeOperationKind; - OperationString = operationString; - } - - /// - /// Gets or sets the kind of the node operation. - /// - /// The kind of the node operation. - internal OperationType NodeOperationKind { get; set; } - - /// - /// Gets or sets the operation string. - /// - /// The operation string. - internal string OperationString { get; set; } - } - - /// - /// The expression node information - /// - private static readonly Dictionary _expressionNodeInfo = new Dictionary - { - { ExpressionNodeType.ConstantValue, new ExpressionNodeInfo(OperationType.Constant, null) }, - { ExpressionNodeType.ConstantParameter, new ExpressionNodeInfo(OperationType.Constant, null) }, - { ExpressionNodeType.CurrentValueProperty, new ExpressionNodeInfo(OperationType.Reference, null) }, - { ExpressionNodeType.Reference, new ExpressionNodeInfo(OperationType.Reference, null) }, - { ExpressionNodeType.ReferenceProperty, new ExpressionNodeInfo(OperationType.Reference, null) }, - { ExpressionNodeType.StartingValueProperty, new ExpressionNodeInfo(OperationType.Reference, null) }, - { ExpressionNodeType.TargetReference, new ExpressionNodeInfo(OperationType.Reference, null) }, - { ExpressionNodeType.Conditional, new ExpressionNodeInfo(OperationType.Conditional, null) }, - { ExpressionNodeType.Swizzle, new ExpressionNodeInfo(OperationType.Swizzle, null) }, - { ExpressionNodeType.Add, new ExpressionNodeInfo(OperationType.Operator, "+") }, - { ExpressionNodeType.And, new ExpressionNodeInfo(OperationType.Operator, "&&") }, - { ExpressionNodeType.Divide, new ExpressionNodeInfo(OperationType.Operator, "/") }, - { ExpressionNodeType.Equals, new ExpressionNodeInfo(OperationType.Operator, "==") }, - { ExpressionNodeType.GreaterThan, new ExpressionNodeInfo(OperationType.Operator, ">") }, - { ExpressionNodeType.GreaterThanEquals, new ExpressionNodeInfo(OperationType.Operator, ">=") }, - { ExpressionNodeType.LessThan, new ExpressionNodeInfo(OperationType.Operator, "<") }, - { ExpressionNodeType.LessThanEquals, new ExpressionNodeInfo(OperationType.Operator, "<=") }, - { ExpressionNodeType.Multiply, new ExpressionNodeInfo(OperationType.Operator, "*") }, - { ExpressionNodeType.Not, new ExpressionNodeInfo(OperationType.UnaryOperator, "!") }, - { ExpressionNodeType.NotEquals, new ExpressionNodeInfo(OperationType.Operator, "!=") }, - { ExpressionNodeType.Or, new ExpressionNodeInfo(OperationType.Operator, "||") }, - { ExpressionNodeType.Subtract, new ExpressionNodeInfo(OperationType.Operator, "-") }, - { ExpressionNodeType.Absolute, new ExpressionNodeInfo(OperationType.Function, "abs") }, - { ExpressionNodeType.Acos, new ExpressionNodeInfo(OperationType.Function, "acos") }, - { ExpressionNodeType.Asin, new ExpressionNodeInfo(OperationType.Function, "asin") }, - { ExpressionNodeType.Atan, new ExpressionNodeInfo(OperationType.Function, "atan") }, - { ExpressionNodeType.Cos, new ExpressionNodeInfo(OperationType.Function, "cos") }, - { ExpressionNodeType.Ceil, new ExpressionNodeInfo(OperationType.Function, "ceil") }, - { ExpressionNodeType.Clamp, new ExpressionNodeInfo(OperationType.Function, "clamp") }, - { ExpressionNodeType.ColorHsl, new ExpressionNodeInfo(OperationType.Function, "colorhsl") }, - { ExpressionNodeType.ColorRgb, new ExpressionNodeInfo(OperationType.Function, "colorrgb") }, - { ExpressionNodeType.ColorLerp, new ExpressionNodeInfo(OperationType.Function, "colorlerp") }, - { ExpressionNodeType.ColorLerpHsl, new ExpressionNodeInfo(OperationType.Function, "colorhsllerp") }, - { ExpressionNodeType.ColorLerpRgb, new ExpressionNodeInfo(OperationType.Function, "colorrgblerp") }, - { ExpressionNodeType.Concatenate, new ExpressionNodeInfo(OperationType.Function, "concatenate") }, - { ExpressionNodeType.Distance, new ExpressionNodeInfo(OperationType.Function, "distance") }, - { ExpressionNodeType.DistanceSquared, new ExpressionNodeInfo(OperationType.Function, "distancesquared") }, - { ExpressionNodeType.Floor, new ExpressionNodeInfo(OperationType.Function, "floor") }, - { ExpressionNodeType.Inverse, new ExpressionNodeInfo(OperationType.Function, "inverse") }, - { ExpressionNodeType.Length, new ExpressionNodeInfo(OperationType.Function, "length") }, - { ExpressionNodeType.LengthSquared, new ExpressionNodeInfo(OperationType.Function, "lengthsquared") }, - { ExpressionNodeType.Lerp, new ExpressionNodeInfo(OperationType.Function, "lerp") }, - { ExpressionNodeType.Ln, new ExpressionNodeInfo(OperationType.Function, "ln") }, - { ExpressionNodeType.Log10, new ExpressionNodeInfo(OperationType.Function, "log10") }, - { ExpressionNodeType.Max, new ExpressionNodeInfo(OperationType.Function, "max") }, - { ExpressionNodeType.Matrix3x2FromRotation, new ExpressionNodeInfo(OperationType.Function, "matrix3x2.createrotation") }, - { ExpressionNodeType.Matrix3x2FromScale, new ExpressionNodeInfo(OperationType.Function, "matrix3x2.createscale") }, - { ExpressionNodeType.Matrix3x2FromSkew, new ExpressionNodeInfo(OperationType.Function, "matrix3x2.createskew") }, - { ExpressionNodeType.Matrix3x2FromTranslation, new ExpressionNodeInfo(OperationType.Function, "matrix3x2.createtranslation") }, - { ExpressionNodeType.Matrix3x2, new ExpressionNodeInfo(OperationType.Function, "matrix3x2") }, - { ExpressionNodeType.Matrix4x4FromAxisAngle, new ExpressionNodeInfo(OperationType.Function, "matrix4x4.createfromaxisangle") }, - { ExpressionNodeType.Matrix4x4FromScale, new ExpressionNodeInfo(OperationType.Function, "matrix4x4.createscale") }, - { ExpressionNodeType.Matrix4x4FromTranslation, new ExpressionNodeInfo(OperationType.Function, "matrix4x4.createtranslation") }, - { ExpressionNodeType.Matrix4x4, new ExpressionNodeInfo(OperationType.Function, "matrix4x4") }, - { ExpressionNodeType.Min, new ExpressionNodeInfo(OperationType.Function, "min") }, - { ExpressionNodeType.Modulus, new ExpressionNodeInfo(OperationType.Function, "mod") }, - { ExpressionNodeType.Negate, new ExpressionNodeInfo(OperationType.Function, "-") }, - { ExpressionNodeType.Normalize, new ExpressionNodeInfo(OperationType.Function, "normalize") }, - { ExpressionNodeType.Pow, new ExpressionNodeInfo(OperationType.Function, "pow") }, - { ExpressionNodeType.QuaternionFromAxisAngle, new ExpressionNodeInfo(OperationType.Function, "quaternion.createfromaxisangle") }, - { ExpressionNodeType.Quaternion, new ExpressionNodeInfo(OperationType.Function, "quaternion") }, - { ExpressionNodeType.Round, new ExpressionNodeInfo(OperationType.Function, "round") }, - { ExpressionNodeType.Scale, new ExpressionNodeInfo(OperationType.Function, "scale") }, - { ExpressionNodeType.Sin, new ExpressionNodeInfo(OperationType.Function, "sin") }, - { ExpressionNodeType.Slerp, new ExpressionNodeInfo(OperationType.Function, "slerp") }, - { ExpressionNodeType.Sqrt, new ExpressionNodeInfo(OperationType.Function, "sqrt") }, - { ExpressionNodeType.Square, new ExpressionNodeInfo(OperationType.Function, "square") }, - { ExpressionNodeType.Tan, new ExpressionNodeInfo(OperationType.Function, "tan") }, - { ExpressionNodeType.ToDegrees, new ExpressionNodeInfo(OperationType.Function, "todegrees") }, - { ExpressionNodeType.ToRadians, new ExpressionNodeInfo(OperationType.Function, "toradians") }, - { ExpressionNodeType.Transform, new ExpressionNodeInfo(OperationType.Function, "transform") }, - { ExpressionNodeType.Vector2, new ExpressionNodeInfo(OperationType.Function, "vector2") }, - { ExpressionNodeType.Vector3, new ExpressionNodeInfo(OperationType.Function, "vector3") }, - { ExpressionNodeType.Vector4, new ExpressionNodeInfo(OperationType.Function, "vector4") }, - }; - } -} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/BooleanNode.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/BooleanNode.cs deleted file mode 100644 index 0b4dca317..000000000 --- a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/BooleanNode.cs +++ /dev/null @@ -1,195 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; - -namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork -{ - // Ignore warning: 'BooleanNode' defines operator == or operator != but does not override Object.Equals(object o) && Object.GetHashCode() -#pragma warning disable CS0660, CS0661 - /// - /// Class BooleanNode. This class cannot be inherited. - /// - /// - public sealed class BooleanNode : ExpressionNode - { - /// - /// Initializes a new instance of the class. - /// - internal BooleanNode() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// if set to true [value]. - internal BooleanNode(bool value) - { - _value = value; - NodeType = ExpressionNodeType.ConstantValue; - } - - /// - /// Initializes a new instance of the class. - /// - /// Name of the parameter. - internal BooleanNode(string paramName) - { - ParamName = paramName; - NodeType = ExpressionNodeType.ConstantParameter; - } - - /// - /// Initializes a new instance of the class. - /// - /// Name of the parameter. - /// if set to true [value]. - internal BooleanNode(string paramName, bool value) - { - ParamName = paramName; - _value = value; - NodeType = ExpressionNodeType.ConstantParameter; - - SetBooleanParameter(paramName, value); - } - - /// - /// Performs an implicit conversion from to . - /// - /// if set to true [value]. - /// The result of the conversion. - public static implicit operator BooleanNode(bool value) - { - return new BooleanNode(value); - } - - /// - /// Implements the == operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static BooleanNode operator ==(BooleanNode left, BooleanNode right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Equals, left, right); - } - - /// - /// Implements the != operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static BooleanNode operator !=(BooleanNode left, BooleanNode right) - { - return ExpressionFunctions.Function(ExpressionNodeType.NotEquals, left, right); - } - - /// - /// Implements the & operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static BooleanNode operator &(BooleanNode left, BooleanNode right) - { - return ExpressionFunctions.Function(ExpressionNodeType.And, left, right); - } - - /// - /// Implements the | operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static BooleanNode operator |(BooleanNode left, BooleanNode right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Or, left, right); - } - - /// - /// Implements the ! operator. - /// - /// The value. - /// The result of the operator. - public static BooleanNode operator !(BooleanNode value) - { - return ExpressionFunctions.Function(ExpressionNodeType.Not, value); - } - - /// - /// Gets the value. - /// - /// System.String. - protected internal override string GetValue() - { - return _value ? "true" : "false"; - } - - private bool _value; - - /// - /// Evaluates the current value of the expression - /// - /// The current value of the expression - public bool Evaluate() - { - switch (NodeType) - { - case ExpressionNodeType.ConstantValue: - return _value; - case ExpressionNodeType.Equals: - return Equals(Children[0], Children[1]); - case ExpressionNodeType.NotEquals: - return !Equals(Children[0], Children[1]); - case ExpressionNodeType.And: - return (Children[0] as BooleanNode).Evaluate() && (Children[1] as BooleanNode).Evaluate(); - case ExpressionNodeType.Or: - return (Children[0] as BooleanNode).Evaluate() || (Children[1] as BooleanNode).Evaluate(); - case ExpressionNodeType.LessThan: - return (Children[0] as ScalarNode).Evaluate() < (Children[1] as ScalarNode).Evaluate(); - case ExpressionNodeType.LessThanEquals: - return (Children[0] as ScalarNode).Evaluate() <= (Children[1] as ScalarNode).Evaluate(); - case ExpressionNodeType.GreaterThan: - return (Children[0] as ScalarNode).Evaluate() > (Children[1] as ScalarNode).Evaluate(); - case ExpressionNodeType.GreaterThanEquals: - return (Children[0] as ScalarNode).Evaluate() >= (Children[1] as ScalarNode).Evaluate(); - case ExpressionNodeType.Not: - return !(Children[0] as BooleanNode).Evaluate(); - case ExpressionNodeType.ReferenceProperty: - var reference = (Children[0] as ReferenceNode).Reference; - switch (PropertyName) - { - default: - reference.Properties.TryGetBoolean(PropertyName, out var referencedProperty); - return referencedProperty; - } - - case ExpressionNodeType.Conditional: - return - (Children[0] as BooleanNode).Evaluate() ? - (Children[1] as BooleanNode).Evaluate() : - (Children[2] as BooleanNode).Evaluate(); - default: - throw new NotImplementedException(); - } - - bool Equals(ExpressionNode e1, ExpressionNode e2) => (e1, e2) switch - { - (BooleanNode n1, BooleanNode n2) => n1.Evaluate() == n2.Evaluate(), - (ScalarNode n1, ScalarNode n2) => n1.Evaluate() == n2.Evaluate(), - (Vector2Node n1, Vector2Node n2) => n1.Evaluate() == n2.Evaluate(), - (Vector3Node n1, Vector3Node n2) => n1.Evaluate() == n2.Evaluate(), - (Vector4Node n1, Vector4Node n2) => n1.Evaluate() == n2.Evaluate(), - (ColorNode n1, ColorNode n2) => n1.Evaluate() == n2.Evaluate(), - (QuaternionNode n1, QuaternionNode n2) => n1.Evaluate() == n2.Evaluate(), - (Matrix3x2Node n1, Matrix3x2Node n2) => n1.Evaluate() == n2.Evaluate(), - (Matrix4x4Node n1, Matrix4x4Node n2) => n1.Evaluate() == n2.Evaluate(), - _ => false - }; - } - } -#pragma warning restore CS0660, CS0661 -} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/ColorNode.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/ColorNode.cs deleted file mode 100644 index b0566e70a..000000000 --- a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/ColorNode.cs +++ /dev/null @@ -1,138 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using Windows.UI; -using Windows.UI.Composition; - -namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork -{ - // Ignore warning: 'ColorNode' defines operator == or operator != but does not override Object.Equals(object o) && Object.GetHashCode() -#pragma warning disable CS0660, CS0661 - /// - /// Class ColorNode. This class cannot be inherited. - /// - /// - public sealed class ColorNode : ExpressionNode - { - /// - /// Initializes a new instance of the class. - /// - internal ColorNode() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The value. - internal ColorNode(Color value) - { - _value = value; - NodeType = ExpressionNodeType.ConstantValue; - } - - /// - /// Initializes a new instance of the class. - /// - /// Name of the parameter. - internal ColorNode(string paramName) - { - ParamName = paramName; - NodeType = ExpressionNodeType.ConstantParameter; - } - - /// - /// Initializes a new instance of the class. - /// - /// Name of the parameter. - /// The value. - internal ColorNode(string paramName, Color value) - { - ParamName = paramName; - _value = value; - NodeType = ExpressionNodeType.ConstantParameter; - - SetColorParameter(paramName, value); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator ColorNode(Color value) - { - return new ColorNode(value); - } - - /// - /// Implements the == operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static BooleanNode operator ==(ColorNode left, ColorNode right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Equals, left, right); - } - - /// - /// Implements the != operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static BooleanNode operator !=(ColorNode left, ColorNode right) - { - return ExpressionFunctions.Function(ExpressionNodeType.NotEquals, left, right); - } - - /// - /// Gets the value. - /// - /// System.String. - protected internal override string GetValue() - { - return $"ColorRgb({_value.A},{_value.R},{_value.G},{_value.B})"; - } - - private Color _value; - - /// - /// Evaluates the current value of the expression - /// - /// The current value of the expression - public Color Evaluate() - { - switch (NodeType) - { - case ExpressionNodeType.ConstantValue: - return _value; - case ExpressionNodeType.ReferenceProperty: - var reference = (Children[0] as ReferenceNode).Reference; - return PropertyName switch - { - nameof(CompositionColorBrush.Color) => (reference as CompositionColorBrush).Color, - _ => GetProperty() - }; - - Color GetProperty() - { - reference.Properties.TryGetColor(PropertyName, out var value); - return value; - } - - case ExpressionNodeType.Conditional: - return - (Children[0] as BooleanNode).Evaluate() ? - (Children[1] as ColorNode).Evaluate() : - (Children[2] as ColorNode).Evaluate(); - default: - throw new NotImplementedException(); - } - } - } -#pragma warning restore CS0660, CS0661 -} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/ExpressionNode.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/ExpressionNode.cs deleted file mode 100644 index e97bbee51..000000000 --- a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/ExpressionNode.cs +++ /dev/null @@ -1,720 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.Numerics; -using System.Runtime.CompilerServices; -using Windows.UI; -using Windows.UI.Composition; - -namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork -{ - /// - /// Class ExpressionNode. - /// - public abstract class ExpressionNode : IDisposable - { - private List _objRefList = null; - private Dictionary _compObjToParamNameMap = null; - private Dictionary _constParamMap = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - - /// - /// Initializes a new instance of the class. - /// - internal ExpressionNode() - { - } - - /// - /// Resolve a named reference parameter to the CompositionObject it will refer to. - /// - /// The string name of the parameter to be resolved. - /// The composition object that the parameter should resolve to. - public void SetReferenceParameter(string parameterName, CompositionObject compObj) - { - // Make sure we have our reference list populated - EnsureReferenceInfo(); - - for (int i = 0; i < _objRefList.Count; i++) - { - if (string.Compare(_objRefList[i].ParameterName, parameterName, true /*ignoreCase*/) == 0) - { - var item = _objRefList[i]; - item.CompObject = compObj; - _objRefList[i] = item; - } - } - } - - /// - /// Resolve a named parameter to the boolean value it will use. - /// - /// The string name of the parameter to be resolved. - /// The value that the parameter should resolve to. - public void SetBooleanParameter(string parameterName, bool value) - { - _constParamMap[parameterName] = value; - } - - /// - /// Resolve a named parameter to the float value it will use. - /// - /// The string name of the parameter to be resolved. - /// The value that the parameter should resolve to. - public void SetScalarParameter(string parameterName, float value) - { - _constParamMap[parameterName] = value; - } - - /// - /// Resolve a named parameter to the Vector2 value it will use. - /// - /// The string name of the parameter to be resolved. - /// The value that the parameter should resolve to. - public void SetVector2Parameter(string parameterName, Vector2 value) - { - _constParamMap[parameterName] = value; - } - - /// - /// Resolve a named parameter to the Vector3 value it will use. - /// - /// The string name of the parameter to be resolved. - /// The value that the parameter should resolve to. - public void SetVector3Parameter(string parameterName, Vector3 value) - { - _constParamMap[parameterName] = value; - } - - /// - /// Resolve a named parameter to the Vector4 value it will use. - /// - /// The string name of the parameter to be resolved. - /// The value that the parameter should resolve to. - public void SetVector4Parameter(string parameterName, Vector4 value) - { - _constParamMap[parameterName] = value; - } - - /// - /// Resolve a named parameter to the Color value it will use. - /// - /// The string name of the parameter to be resolved. - /// The value that the parameter should resolve to. - public void SetColorParameter(string parameterName, Color value) - { - _constParamMap[parameterName] = value; - } - - /// - /// Resolve a named parameter to the Quaternion value it will use. - /// - /// The string name of the parameter to be resolved. - /// The value that the parameter should resolve to. - public void SetQuaternionParameter(string parameterName, Quaternion value) - { - _constParamMap[parameterName] = value; - } - - /// - /// Resolve a named parameter to the Matrix3x2 value it will use. - /// - /// The string name of the parameter to be resolved. - /// The value that the parameter should resolve to. - public void SetMatrix3x2Parameter(string parameterName, Matrix3x2 value) - { - _constParamMap[parameterName] = value; - } - - /// - /// Resolve a named parameter to the Matrix4x4 value it will use. - /// - /// The string name of the parameter to be resolved. - /// The value that the parameter should resolve to. - public void SetMatrix4x4Parameter(string parameterName, Matrix4x4 value) - { - _constParamMap[parameterName] = value; - } - - /// - /// Releases all resources used by this ExpressionNode. - /// - public void Dispose() - { - _objRefList = null; - _compObjToParamNameMap = null; - _constParamMap = null; - Subchannels = null; - PropertyName = null; - NodeType = ExpressionNodeType.Count; - - // Note: we don't recursively dispose all child nodes, as those nodes could be in use by a different Expression - Children = null; - - if (ExpressionAnimation != null) - { - ExpressionAnimation.Dispose(); - ExpressionAnimation = null; - } - } - - /// - /// Creates the expression node. - /// - /// A class that derives from ExpressionNode - /// T. - /// unexpected type - internal static T CreateExpressionNode() - where T : ExpressionNode - { - T newNode; - - if (typeof(T) == typeof(BooleanNode)) - { - newNode = new BooleanNode() as T; - } - else if (typeof(T) == typeof(ScalarNode)) - { - newNode = new ScalarNode() as T; - } - else if (typeof(T) == typeof(Vector2Node)) - { - newNode = new Vector2Node() as T; - } - else if (typeof(T) == typeof(Vector3Node)) - { - newNode = new Vector3Node() as T; - } - else if (typeof(T) == typeof(Vector4Node)) - { - newNode = new Vector4Node() as T; - } - else if (typeof(T) == typeof(ColorNode)) - { - newNode = new ColorNode() as T; - } - else if (typeof(T) == typeof(QuaternionNode)) - { - newNode = new QuaternionNode() as T; - } - else if (typeof(T) == typeof(Matrix3x2Node)) - { - newNode = new Matrix3x2Node() as T; - } - else if (typeof(T) == typeof(Matrix4x4Node)) - { - newNode = new Matrix4x4Node() as T; - } - else - { - throw new Exception("unexpected type"); - } - - return newNode; - } - - /// - /// Creates the value keyword. - /// - /// A class that derives from ExpressionNode - /// Kind of the keyword. - /// T. - /// Invalid ValueKeywordKind - internal static T CreateValueKeyword(ValueKeywordKind keywordKind) - where T : ExpressionNode - { - T node = CreateExpressionNode(); - - (node as ExpressionNode).ParamName = null; - - switch (keywordKind) - { - case ValueKeywordKind.CurrentValue: - (node as ExpressionNode).NodeType = ExpressionNodeType.CurrentValueProperty; - break; - - case ValueKeywordKind.StartingValue: - (node as ExpressionNode).NodeType = ExpressionNodeType.StartingValueProperty; - break; - - default: - throw new Exception("Invalid ValueKeywordKind"); - } - - return node; - } - - /// - /// To the expression string. - /// - /// System.String. - internal string ToExpressionString() - { - if (_objRefList == null) - { - EnsureReferenceInfo(); - } - - return ToExpressionStringInternal(); - } - - /// - /// Clears the reference information. - /// - /// Reference and paramName can't both be null - internal void ClearReferenceInfo() - { - _objRefList = null; - ParamName = null; - foreach (var child in Children) - { - child.ClearReferenceInfo(); - } - } - - /// - /// Ensures the reference information. - /// - /// Reference and paramName can't both be null - internal void EnsureReferenceInfo() - { - if (_objRefList == null) - { - // Get all ReferenceNodes in this expression - HashSet referenceNodes = new HashSet(); - PopulateParameterNodes(ref _constParamMap, ref referenceNodes); - - // Find all CompositionObjects across all referenceNodes that need a paramName to be created - HashSet compObjects = new HashSet(); - foreach (var refNode in referenceNodes) - { - if ((refNode.Reference != null) && (refNode.GetReferenceParamString() == null)) - { - compObjects.Add(refNode.Reference); - } - } - - // Create a map to store the generated paramNames for each CompObj - _compObjToParamNameMap = new Dictionary(); - var paramCount = 0u; - foreach (var compObj in compObjects) - { - string paramName = CreateUniqueParamNameFromIndex(paramCount++); - - _compObjToParamNameMap.Add(compObj, paramName); - } - - // Go through all reference nodes again to create our full list of referenceInfo. This time, if - // the param name is null, look it up from our new map and store it. - _objRefList = new List(); - foreach (var refNode in referenceNodes) - { - string paramName = refNode.GetReferenceParamString(); - - if ((refNode.Reference == null) && (paramName == null)) - { - // This can't happen - if the ref is null it must be because it's a named param - throw new Exception("Reference and paramName can't both be null"); - } - - if (paramName == null) - { - paramName = _compObjToParamNameMap[refNode.Reference]; - } - - _objRefList.Add(new ReferenceInfo(paramName, refNode.Reference)); - refNode.ParamName = paramName; - } - } - - // Generates Excel-column-like identifiers, e.g. A, B, ..., Z, AA, BA... - // This implementation aggregates characters in reverse order to avoid having to - // precompute the exact number of characters in the resulting string. This is not - // important in this context as the only critical property to maintain is to have - // a unique mapping to each input value to the resulting sequence of letters. - //[System.Runtime.CompilerServices.SkipLocalsInit] - static unsafe string CreateUniqueParamNameFromIndex(uint i) - { - const int alphabetLength = 'Z' - 'A' + 1; - - // The total length of the resulting sequence is guaranteed to always - // be less than 8, given that log26(4294967295) ≈ 6.8. In this case we - // are just allocating the immediate next power of two following that. - // Note: this is using a char* buffer instead of Span as the latter - // is not referenced here, and we don't want to pull in an extra package. - char* characters = stackalloc char[8]; - - characters[0] = (char)('A' + (i % alphabetLength)); - - int totalCharacters = 1; - - while ((i /= alphabetLength) > 0) - { - i--; - - characters[totalCharacters++] = (char)('A' + (i % alphabetLength)); - } - - return new string(characters, 0, totalCharacters); - } - } - - /// - /// Sets all parameters. - /// - /// The animation. - internal void SetAllParameters(CompositionAnimation animation) - { - // Make sure the list is populated - EnsureReferenceInfo(); - - foreach (var refInfo in _objRefList) - { - animation.SetReferenceParameter(refInfo.ParameterName, refInfo.CompObject); - } - - foreach (var constParam in _constParamMap) - { - if (constParam.Value.GetType() == typeof(bool)) - { - animation.SetBooleanParameter(constParam.Key, (bool)constParam.Value); - } - else if (constParam.Value.GetType() == typeof(float)) - { - animation.SetScalarParameter(constParam.Key, (float)constParam.Value); - } - else if (constParam.Value.GetType() == typeof(Vector2)) - { - animation.SetVector2Parameter(constParam.Key, (Vector2)constParam.Value); - } - else if (constParam.Value.GetType() == typeof(Vector3)) - { - animation.SetVector3Parameter(constParam.Key, (Vector3)constParam.Value); - } - else if (constParam.Value.GetType() == typeof(Vector4)) - { - animation.SetVector4Parameter(constParam.Key, (Vector4)constParam.Value); - } - else if (constParam.Value.GetType() == typeof(Color)) - { - animation.SetColorParameter(constParam.Key, (Color)constParam.Value); - } - else if (constParam.Value.GetType() == typeof(Quaternion)) - { - animation.SetQuaternionParameter(constParam.Key, (Quaternion)constParam.Value); - } - else if (constParam.Value.GetType() == typeof(Matrix3x2)) - { - animation.SetMatrix3x2Parameter(constParam.Key, (Matrix3x2)constParam.Value); - } - else if (constParam.Value.GetType() == typeof(Matrix4x4)) - { - animation.SetMatrix4x4Parameter(constParam.Key, (Matrix4x4)constParam.Value); - } - else - { - throw new Exception($"Unexpected constant parameter datatype ({constParam.Value.GetType()})"); - } - } - } - - /// - /// Gets the value. - /// - /// System.String. - protected internal abstract string GetValue(); - - /// - /// Subchannelses the internal. - /// - /// A class that derives from ExpressionNode. - /// The subchannels. - /// T. - protected internal T SubchannelsInternal(params string[] subchannels) - where T : ExpressionNode - { - ExpressionNodeType swizzleNodeType = ExpressionNodeType.Swizzle; - T newNode; - - switch (subchannels.GetLength(0)) - { - case 1: - newNode = ExpressionFunctions.Function(swizzleNodeType, this) as T; - break; - - case 2: - newNode = ExpressionFunctions.Function(swizzleNodeType, this) as T; - break; - - case 3: - newNode = ExpressionFunctions.Function(swizzleNodeType, this) as T; - break; - - case 4: - newNode = ExpressionFunctions.Function(swizzleNodeType, this) as T; - break; - - case 6: - newNode = ExpressionFunctions.Function(swizzleNodeType, this) as T; - break; - - case 16: - newNode = ExpressionFunctions.Function(swizzleNodeType, this) as T; - break; - - default: - throw new Exception($"Invalid subchannel count ({subchannels.GetLength(0)})"); - } - - (newNode as ExpressionNode).Subchannels = subchannels; - - return newNode; - } - - /// - /// Populates the parameter nodes. - /// - /// The constant parameter map. - /// The reference nodes. - protected internal void PopulateParameterNodes(ref Dictionary constParamMap, ref HashSet referenceNodes) - { - var refNode = this as ReferenceNode; - if ((refNode != null) && (refNode.NodeType != ExpressionNodeType.TargetReference)) - { - referenceNodes.Add(refNode); - } - - if ((_constParamMap != null) && (_constParamMap != constParamMap)) - { - foreach (var entry in _constParamMap) - { - // If this parameter hasn't already been set on the root, use this node's parameter info - if (!constParamMap.ContainsKey(entry.Key)) - { - constParamMap[entry.Key] = entry.Value; - } - } - } - - foreach (var child in Children) - { - child.PopulateParameterNodes(ref constParamMap, ref referenceNodes); - } - } - - private OperationType GetOperationKind() - { - return ExpressionFunctions.GetNodeInfoFromType(NodeType).NodeOperationKind; - } - - private string GetOperationString() - { - return ExpressionFunctions.GetNodeInfoFromType(NodeType).OperationString; - } - - private string ToExpressionStringInternal() - { - string ret; - - // Do a recursive depth-first traversal of the node tree to print out the full expression string - switch (GetOperationKind()) - { - case OperationType.Function: - if (Children.Count == 0) - { - throw new Exception("Can't have an expression function with no params"); - } - - ret = $"{GetOperationString()}({Children[0].ToExpressionStringInternal()}"; - for (int i = 1; i < Children.Count; i++) - { - ret += "," + Children[i].ToExpressionStringInternal(); - } - - ret += ")"; - break; - - case OperationType.Operator: - if (Children.Count != 2) - { - throw new Exception("Can't have an operator that doesn't have 2 exactly params"); - } - - ret = $"({Children[0].ToExpressionStringInternal()} {GetOperationString()} {Children[1].ToExpressionStringInternal()})"; - break; - - case OperationType.UnaryOperator: - if (Children.Count != 1) - { - throw new Exception("Can't have an unary operator that doesn't have exactly one params"); - } - - ret = $"( {GetOperationString()} {Children[0].ToExpressionStringInternal()} )"; - break; - - case OperationType.Constant: - if (Children.Count == 0) - { - // If a parameterName was specified, use it. Otherwise write the value. - ret = ParamName ?? GetValue(); - } - else - { - throw new Exception("Constants must have 0 children"); - } - - break; - - case OperationType.Swizzle: - if (Children.Count != 1) - { - throw new Exception("Swizzles should have exactly 1 child"); - } - - string swizzleString = string.Empty; - foreach (var sub in Subchannels) - { - swizzleString += sub; - } - - ret = $"{Children[0].ToExpressionStringInternal()}.{swizzleString}"; - break; - - case OperationType.Reference: - if ((NodeType == ExpressionNodeType.Reference) || - (NodeType == ExpressionNodeType.TargetReference)) - { - // This is the reference node itself - if (Children.Count != 0) - { - throw new Exception("References cannot have children"); - } - - ret = (this as ReferenceNode).GetReferenceParamString(); - } - else if (NodeType == ExpressionNodeType.ReferenceProperty) - { - // This is the property node of the reference - if (Children.Count != 1) - { - throw new Exception("Reference properties must have exactly one child"); - } - - if (PropertyName == null) - { - throw new Exception("Reference properties must have a property name"); - } - - ret = $"{Children[0].ToExpressionStringInternal()}.{PropertyName}"; - } - else if (NodeType == ExpressionNodeType.StartingValueProperty) - { - // This is a "this.StartingValue" node - if (Children.Count != 0) - { - throw new Exception("StartingValue references Cannot have children"); - } - - ret = "this.StartingValue"; - } - else if (NodeType == ExpressionNodeType.CurrentValueProperty) - { - // This is a "this.CurrentValue" node - if (Children.Count != 0) - { - throw new Exception("CurrentValue references Cannot have children"); - } - - ret = "this.CurrentValue"; - } - else - { - throw new Exception("Unexpected NodeType for OperationType.Reference"); - } - - break; - - case OperationType.Conditional: - if (Children.Count != 3) - { - throw new Exception("Conditionals must have exactly 3 children"); - } - - ret = $"(({Children[0].ToExpressionStringInternal()}) ? ({Children[1].ToExpressionStringInternal()}) : ({Children[2].ToExpressionStringInternal()}))"; - break; - - default: - throw new Exception($"Unexpected operation type ({GetOperationKind()}), nodeType = {NodeType}"); - } - - return ret; - } - - /// - /// Struct ReferenceInfo - /// - internal struct ReferenceInfo - { - /// - /// Initializes a new instance of the struct. - /// - /// Name of the parameter. - /// The comp object. - public ReferenceInfo(string paramName, CompositionObject compObj) - { - ParameterName = paramName; - CompObject = compObj; - } - - /// - /// Gets or sets the name of the parameter. - /// - /// The name of the parameter. - public string ParameterName { get; set; } - - /// - /// Gets or sets the comp object. - /// - /// The comp object. - public CompositionObject CompObject { get; set; } - } - - /// - /// Gets or sets the name of the property. - /// - /// The name of the property. - internal string PropertyName { get; set; } - - /// - /// Gets or sets the type of the node. - /// - /// The type of the node. - internal ExpressionNodeType NodeType { get; set; } - - /// - /// Gets or sets the children. - /// - /// The children. - internal List Children { get; set; } = new List(); - - /// - /// Gets or sets the name of the parameter. - /// - /// The name of the parameter. - internal string ParamName { get; set; } - - /// - /// Gets or sets the expression animation. - /// - /// The expression animation. - internal ExpressionAnimation ExpressionAnimation { get; set; } - - /// - /// Gets or sets the subchannels. - /// - /// The subchannels. - protected internal string[] Subchannels { get; set; } - } -} diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/ExpressionNodeType.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/ExpressionNodeType.cs deleted file mode 100644 index 44089ce2b..000000000 --- a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/ExpressionNodeType.cs +++ /dev/null @@ -1,387 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork -{ - /// - /// Enum ExpressionNodeType - /// - internal enum ExpressionNodeType - { - /// - /// The constant value - /// - ConstantValue, - - /// - /// The constant parameter - /// - ConstantParameter, - - /// - /// The current value property - /// - CurrentValueProperty, - - /// - /// The reference - /// - Reference, - - /// - /// The reference property - /// - ReferenceProperty, - - /// - /// The starting value property - /// - StartingValueProperty, - - /// - /// The target reference - /// - TargetReference, - - /// - /// The conditional - /// - Conditional, - - /// - /// The swizzle - /// - Swizzle, - - /// - /// The add - /// - Add, - - /// - /// The and - /// - And, - - /// - /// The divide - /// - Divide, - - /// - /// The equals - /// - Equals, - - /// - /// The greater than - /// - GreaterThan, - - /// - /// The greater than equals - /// - GreaterThanEquals, - - /// - /// The less than - /// - LessThan, - - /// - /// The less than equals - /// - LessThanEquals, - - /// - /// The multiply - /// - Multiply, - - /// - /// The not - /// - Not, - - /// - /// The not equals - /// - NotEquals, - - /// - /// The or - /// - Or, - - /// - /// The subtract - /// - Subtract, - - /// - /// The absolute - /// - Absolute, - - /// - /// The acos - /// - Acos, - - /// - /// The asin - /// - Asin, - - /// - /// The atan - /// - Atan, - - /// - /// The cos - /// - Cos, - - /// - /// The ceil - /// - Ceil, - - /// - /// The clamp - /// - Clamp, - - /// - /// The color HSL - /// - ColorHsl, - - /// - /// The color RGB - /// - ColorRgb, - - /// - /// The color lerp - /// - ColorLerp, - - /// - /// The color lerp HSL - /// - ColorLerpHsl, - - /// - /// The color lerp RGB - /// - ColorLerpRgb, - - /// - /// The concatenate - /// - Concatenate, - - /// - /// The distance - /// - Distance, - - /// - /// The distance squared - /// - DistanceSquared, - - /// - /// The floor - /// - Floor, - - /// - /// The inverse - /// - Inverse, - - /// - /// The length - /// - Length, - - /// - /// The length squared - /// - LengthSquared, - - /// - /// The lerp - /// - Lerp, - - /// - /// The ln - /// - Ln, - - /// - /// The log10 - /// - Log10, - - /// - /// The maximum - /// - Max, - - /// - /// The matrix3x2 from rotation - /// - Matrix3x2FromRotation, - - /// - /// The matrix3x2 from scale - /// - Matrix3x2FromScale, - - /// - /// The matrix3x2 from skew - /// - Matrix3x2FromSkew, - - /// - /// The matrix3x2 from translation - /// - Matrix3x2FromTranslation, - - /// - /// The matrix3x2 - /// - Matrix3x2, - - /// - /// The matrix4x4 from axis angle - /// - Matrix4x4FromAxisAngle, - - /// - /// The matrix4x4 from scale - /// - Matrix4x4FromScale, - - /// - /// The matrix4x4 from translation - /// - Matrix4x4FromTranslation, - - /// - /// The matrix4x4 - /// - Matrix4x4, - - /// - /// The minimum - /// - Min, - - /// - /// The modulus - /// - Modulus, - - /// - /// The negate - /// - Negate, - - /// - /// The normalize - /// - Normalize, - - /// - /// The pow - /// - Pow, - - /// - /// The quaternion from axis angle - /// - QuaternionFromAxisAngle, - - /// - /// The quaternion - /// - Quaternion, - - /// - /// The round - /// - Round, - - /// - /// The scale - /// - Scale, - - /// - /// The sin - /// - Sin, - - /// - /// The slerp - /// - Slerp, - - /// - /// The SQRT - /// - Sqrt, - - /// - /// The square - /// - Square, - - /// - /// The tan - /// - Tan, - - /// - /// To degrees - /// - ToDegrees, - - /// - /// To radians - /// - ToRadians, - - /// - /// The transform - /// - Transform, - - /// - /// The vector2 - /// - Vector2, - - /// - /// The vector3 - /// - Vector3, - - /// - /// The vector4 - /// - Vector4, - - /// - /// The count - /// - Count - } -} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Matrix3x2Node.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Matrix3x2Node.cs deleted file mode 100644 index 28b964da4..000000000 --- a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Matrix3x2Node.cs +++ /dev/null @@ -1,393 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Numerics; - -namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork -{ - // Ignore warning: 'Matrix3x2Node' defines operator == or operator != but does not override Object.Equals(object o) && Object.GetHashCode() -#pragma warning disable CS0660, CS0661 - - /// - /// Class Matrix3x2Node. This class cannot be inherited. - /// - /// - public sealed class Matrix3x2Node : ExpressionNode - { - /// - /// Initializes a new instance of the class. - /// - internal Matrix3x2Node() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The value. - internal Matrix3x2Node(Matrix3x2 value) - { - _value = value; - NodeType = ExpressionNodeType.ConstantValue; - } - - /// - /// Initializes a new instance of the class. - /// - /// Name of the parameter. - internal Matrix3x2Node(string paramName) - { - ParamName = paramName; - NodeType = ExpressionNodeType.ConstantParameter; - } - - /// - /// Initializes a new instance of the class. - /// - /// Name of the parameter. - /// The value. - internal Matrix3x2Node(string paramName, Matrix3x2 value) - { - ParamName = paramName; - _value = value; - NodeType = ExpressionNodeType.ConstantParameter; - - SetMatrix3x2Parameter(paramName, value); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator Matrix3x2Node(Matrix3x2 value) - { - return new Matrix3x2Node(value); - } - - /// - /// Implements the + operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static Matrix3x2Node operator +(Matrix3x2Node left, Matrix3x2Node right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Add, left, right); - } - - /// - /// Implements the - operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static Matrix3x2Node operator -(Matrix3x2Node left, Matrix3x2Node right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Subtract, left, right); - } - - /// - /// Implements the - operator. - /// - /// The value. - /// The result of the operator. - public static Matrix3x2Node operator -(Matrix3x2Node value) - { - return ExpressionFunctions.Function(ExpressionNodeType.Negate, value); - } - - /// - /// Implements the * operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static Matrix3x2Node operator *(Matrix3x2Node left, ScalarNode right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); - } - - /// - /// Implements the * operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static Matrix3x2Node operator *(Matrix3x2Node left, Matrix3x2Node right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); - } - - /// - /// Implements the == operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static BooleanNode operator ==(Matrix3x2Node left, Matrix3x2Node right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Equals, left, right); - } - - /// - /// Implements the != operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static BooleanNode operator !=(Matrix3x2Node left, Matrix3x2Node right) - { - return ExpressionFunctions.Function(ExpressionNodeType.NotEquals, left, right); - } - - /// - /// Enum Subchannel - /// - public enum Subchannel - { - /// - /// The channel11 - /// - Channel11, - - /// - /// The channel12 - /// - Channel12, - - /// - /// The channel21 - /// - Channel21, - - /// - /// The channel22 - /// - Channel22, - - /// - /// The channel31 - /// - Channel31, - - /// - /// The channel32 - /// - Channel32, - } - - /// - /// Gets the channel11. - /// - /// The channel11. - public ScalarNode Channel11 - { - get { return GetSubchannels(Subchannel.Channel11); } - } - - /// - /// Gets the channel12. - /// - /// The channel12. - public ScalarNode Channel12 - { - get { return GetSubchannels(Subchannel.Channel12); } - } - - /// - /// Gets the channel21. - /// - /// The channel21. - public ScalarNode Channel21 - { - get { return GetSubchannels(Subchannel.Channel21); } - } - - /// - /// Gets the channel22. - /// - /// The channel22. - public ScalarNode Channel22 - { - get { return GetSubchannels(Subchannel.Channel22); } - } - - /// - /// Gets the channel31. - /// - /// The channel31. - public ScalarNode Channel31 - { - get { return GetSubchannels(Subchannel.Channel31); } - } - - /// - /// Gets the channel32. - /// - /// The channel32. - public ScalarNode Channel32 - { - get { return GetSubchannels(Subchannel.Channel32); } - } - - /// - /// Create a new type by re-arranging the Matrix subchannels. - /// - /// The subchannel. - /// ScalarNode - public ScalarNode GetSubchannels(Subchannel s) - { - return SubchannelsInternal(s.ToString()); - } - - /// - /// Create a new type by re-arranging the Matrix subchannels. - /// - /// The first subchannel. - /// The second subchannel. - /// Vector2Node - public Vector2Node GetSubchannels(Subchannel s1, Subchannel s2) - { - return SubchannelsInternal(s1.ToString(), s2.ToString()); - } - - /// - /// Create a new type by re-arranging the Matrix subchannels. - /// - /// The first subchannel. - /// The second subchannel. - /// The third subchannel. - /// Vector3Node - public Vector3Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3) - { - return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString()); - } - - /// - /// Create a new type by re-arranging the Matrix subchannels. - /// - /// The first subchannel. - /// The second subchannel. - /// The third subchannel. - /// The fourth subchannel. - /// Vector4Node - public Vector4Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4) - { - return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString()); - } - - /// - /// Create a new type by re-arranging the Matrix subchannels. - /// - /// The first subchannel. - /// The second subchannel. - /// The third subchannel. - /// The fourth subchannel. - /// The fifth subchannel. - /// The sixth subchannel. - /// Matrix3x2Node - public Matrix3x2Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4, Subchannel s5, Subchannel s6) - { - return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString(), s5.ToString(), s6.ToString()); - } - - /// - /// Create a new type by re-arranging the Matrix subchannels. - /// - /// The first subchannel. - /// The second subchannel. - /// The third subchannel. - /// The fourth subchannel. - /// The fifth subchannel. - /// The sixth subchannel. - /// The seventh subchannel. - /// The eighth subchannel. - /// The ninth subchannel. - /// The tenth subchannel. - /// The eleventh subchannel. - /// The twelfth subchannel. - /// The thirteenth subchannel. - /// The fourteenth subchannel. - /// The fifteenth subchannel. - /// The sixteenth subchannel. - /// Matrix4x4Node -#pragma warning disable SA1117 // Parameters must be on same line or separate lines - public Matrix4x4Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4, - Subchannel s5, Subchannel s6, Subchannel s7, Subchannel s8, - Subchannel s9, Subchannel s10, Subchannel s11, Subchannel s12, - Subchannel s13, Subchannel s14, Subchannel s15, Subchannel s16) - { - return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString(), - s5.ToString(), s6.ToString(), s7.ToString(), s8.ToString(), - s9.ToString(), s10.ToString(), s11.ToString(), s12.ToString(), - s13.ToString(), s14.ToString(), s15.ToString(), s16.ToString()); - } -#pragma warning restore SA1117 // Parameters must be on same line or separate lines - - /// - /// Gets the value. - /// - /// System.String. - protected internal override string GetValue() - { - return $"Matrix3x2({_value.M11.ToCompositionString()},{_value.M12.ToCompositionString()},{_value.M21.ToCompositionString()},{_value.M22.ToCompositionString()},{_value.M31.ToCompositionString()},{_value.M32.ToCompositionString()})"; - } - - private Matrix3x2 _value; - - /// - /// Evaluates the current value of the expression - /// - /// The current value of the expression - public Matrix3x2 Evaluate() - { - switch (NodeType) - { - case ExpressionNodeType.ConstantValue: - return _value; - case ExpressionNodeType.ReferenceProperty: - var reference = (Children[0] as ReferenceNode).Reference; - reference.Properties.TryGetMatrix3x2(PropertyName, out var referencedProperty); - return referencedProperty; - case ExpressionNodeType.Add: - return - (Children[0] as Matrix3x2Node).Evaluate() + - (Children[1] as Matrix3x2Node).Evaluate(); - case ExpressionNodeType.Subtract: - return - (Children[0] as Matrix3x2Node).Evaluate() - - (Children[1] as Matrix3x2Node).Evaluate(); - case ExpressionNodeType.Negate: - return - -(Children[0] as Matrix3x2Node).Evaluate(); - case ExpressionNodeType.Multiply: - return (Children[0], Children[1]) switch - { - (Matrix3x2Node v1, Matrix3x2Node v2) => v1.Evaluate() * v2.Evaluate(), - (Matrix3x2Node v1, ScalarNode s2) => v1.Evaluate() * s2.Evaluate(), - (ScalarNode s1, Matrix3x2Node v2) => v2.Evaluate() * s1.Evaluate(), - _ => throw new NotImplementedException() - }; - case ExpressionNodeType.Conditional: - return - (Children[0] as BooleanNode).Evaluate() ? - (Children[1] as Matrix3x2Node).Evaluate() : - (Children[2] as Matrix3x2Node).Evaluate(); - case ExpressionNodeType.Swizzle: - return new Matrix3x2( - Children[0].EvaluateSubchannel(Subchannels[0]), - Children[0].EvaluateSubchannel(Subchannels[1]), - Children[0].EvaluateSubchannel(Subchannels[2]), - Children[0].EvaluateSubchannel(Subchannels[3]), - Children[0].EvaluateSubchannel(Subchannels[4]), - Children[0].EvaluateSubchannel(Subchannels[5])); - default: - throw new NotImplementedException(); - } - } - } -#pragma warning restore CS0660, CS0661 -} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Matrix4x4Node.Subchannel.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Matrix4x4Node.Subchannel.cs deleted file mode 100644 index f76f4ce42..000000000 --- a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Matrix4x4Node.Subchannel.cs +++ /dev/null @@ -1,99 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork -{ - /// - /// Class Matrix4x4Node. This class cannot be inherited. - /// - /// - public sealed partial class Matrix4x4Node : ExpressionNode - { - /// - /// Enum Subchannel - /// - public enum Subchannel - { - /// - /// The channel11 - /// - Channel11, - - /// - /// The channel12 - /// - Channel12, - - /// - /// The channel13 - /// - Channel13, - - /// - /// The channel14 - /// - Channel14, - - /// - /// The channel21 - /// - Channel21, - - /// - /// The channel22 - /// - Channel22, - - /// - /// The channel23 - /// - Channel23, - - /// - /// The channel24 - /// - Channel24, - - /// - /// The channel31 - /// - Channel31, - - /// - /// The channel32 - /// - Channel32, - - /// - /// The channel33 - /// - Channel33, - - /// - /// The channel34 - /// - Channel34, - - /// - /// The channel41 - /// - Channel41, - - /// - /// The channel42 - /// - Channel42, - - /// - /// The channel43 - /// - Channel43, - - /// - /// The channel44 - /// - Channel44, - } - } -} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Matrix4x4Node.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Matrix4x4Node.cs deleted file mode 100644 index 818648a76..000000000 --- a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Matrix4x4Node.cs +++ /dev/null @@ -1,488 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Numerics; -using Windows.UI.Composition; - -namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork -{ - // Ignore warning: 'Matrix4x4Node' defines operator == or operator != but does not override Object.Equals(object o) && Object.GetHashCode() -#pragma warning disable CS0660, CS0661 - /// - /// Class Matrix4x4Node. This class cannot be inherited. - /// - /// - public sealed partial class Matrix4x4Node : ExpressionNode - { - /// - /// Initializes a new instance of the class. - /// - internal Matrix4x4Node() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The value. - internal Matrix4x4Node(Matrix4x4 value) - { - _value = value; - NodeType = ExpressionNodeType.ConstantValue; - } - - /// - /// Initializes a new instance of the class. - /// - /// Name of the parameter. - internal Matrix4x4Node(string paramName) - { - ParamName = paramName; - NodeType = ExpressionNodeType.ConstantParameter; - } - - /// - /// Initializes a new instance of the class. - /// - /// Name of the parameter. - /// The value. - internal Matrix4x4Node(string paramName, Matrix4x4 value) - { - ParamName = paramName; - _value = value; - NodeType = ExpressionNodeType.ConstantParameter; - - SetMatrix4x4Parameter(paramName, value); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator Matrix4x4Node(Matrix4x4 value) - { - return new Matrix4x4Node(value); - } - - /// - /// Implements the + operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static Matrix4x4Node operator +(Matrix4x4Node left, Matrix4x4Node right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Add, left, right); - } - - /// - /// Implements the - operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static Matrix4x4Node operator -(Matrix4x4Node left, Matrix4x4Node right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Subtract, left, right); - } - - /// - /// Implements the - operator. - /// - /// The value. - /// The result of the operator. - public static Matrix4x4Node operator -(Matrix4x4Node value) - { - return ExpressionFunctions.Function(ExpressionNodeType.Negate, value); - } - - /// - /// Implements the * operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static Matrix4x4Node operator *(Matrix4x4Node left, ScalarNode right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); - } - - /// - /// Implements the * operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static Matrix4x4Node operator *(Matrix4x4Node left, Matrix4x4Node right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); - } - - /// - /// Implements the == operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static BooleanNode operator ==(Matrix4x4Node left, Matrix4x4Node right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Equals, left, right); - } - - /// - /// Implements the != operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static BooleanNode operator !=(Matrix4x4Node left, Matrix4x4Node right) - { - return ExpressionFunctions.Function(ExpressionNodeType.NotEquals, left, right); - } - - /// - /// Gets the channel11. - /// - /// The channel11. - public ScalarNode Channel11 - { - get { return GetSubchannels(Subchannel.Channel11); } - } - - /// - /// Gets the channel12. - /// - /// The channel12. - public ScalarNode Channel12 - { - get { return GetSubchannels(Subchannel.Channel12); } - } - - /// - /// Gets the channel13. - /// - /// The channel13. - public ScalarNode Channel13 - { - get { return GetSubchannels(Subchannel.Channel13); } - } - - /// - /// Gets the channel14. - /// - /// The channel14. - public ScalarNode Channel14 - { - get { return GetSubchannels(Subchannel.Channel14); } - } - - /// - /// Gets the channel21. - /// - /// The channel21. - public ScalarNode Channel21 - { - get { return GetSubchannels(Subchannel.Channel21); } - } - - /// - /// Gets the channel22. - /// - /// The channel22. - public ScalarNode Channel22 - { - get { return GetSubchannels(Subchannel.Channel22); } - } - - /// - /// Gets the channel23. - /// - /// The channel23. - public ScalarNode Channel23 - { - get { return GetSubchannels(Subchannel.Channel23); } - } - - /// - /// Gets the channel24. - /// - /// The channel24. - public ScalarNode Channel24 - { - get { return GetSubchannels(Subchannel.Channel24); } - } - - /// - /// Gets the channel31. - /// - /// The channel31. - public ScalarNode Channel31 - { - get { return GetSubchannels(Subchannel.Channel31); } - } - - /// - /// Gets the channel32. - /// - /// The channel32. - public ScalarNode Channel32 - { - get { return GetSubchannels(Subchannel.Channel32); } - } - - /// - /// Gets the channel33. - /// - /// The channel33. - public ScalarNode Channel33 - { - get { return GetSubchannels(Subchannel.Channel33); } - } - - /// - /// Gets the channel34. - /// - /// The channel34. - public ScalarNode Channel34 - { - get { return GetSubchannels(Subchannel.Channel34); } - } - - /// - /// Gets the channel41. - /// - /// The channel41. - public ScalarNode Channel41 - { - get { return GetSubchannels(Subchannel.Channel41); } - } - - /// - /// Gets the channel42. - /// - /// The channel42. - public ScalarNode Channel42 - { - get { return GetSubchannels(Subchannel.Channel42); } - } - - /// - /// Gets the channel43. - /// - /// The channel43. - public ScalarNode Channel43 - { - get { return GetSubchannels(Subchannel.Channel43); } - } - - /// - /// Gets the channel44. - /// - /// The channel44. - public ScalarNode Channel44 - { - get { return GetSubchannels(Subchannel.Channel44); } - } - - /// - /// Gets the channel11 channel22 channel33. - /// - /// The channel11 channel22 channel33. - public Vector3Node Channel11Channel22Channel33 - { - get { return GetSubchannels(Subchannel.Channel11, Subchannel.Channel22, Subchannel.Channel33); } - } - - /// - /// Gets the channel41 channel42 channel43. - /// - /// The channel41 channel42 channel43. - public Vector3Node Channel41Channel42Channel43 - { - get { return GetSubchannels(Subchannel.Channel41, Subchannel.Channel42, Subchannel.Channel43); } - } - - /// - /// Create a new type by re-arranging the Matrix subchannels. - /// - /// The s. - /// ScalarNode. - public ScalarNode GetSubchannels(Subchannel s) - { - return SubchannelsInternal(s.ToString()); - } - - /// - /// Create a new type by re-arranging the Matrix subchannels. - /// - /// The first subchannel. - /// The second subchannel. - /// Vector2Node - public Vector2Node GetSubchannels(Subchannel s1, Subchannel s2) - { - return SubchannelsInternal(s1.ToString(), s2.ToString()); - } - - /// - /// Create a new type by re-arranging the Matrix subchannels. - /// - /// The first subchannel. - /// The second subchannel. - /// The third subchannel. - /// Vector3Node - public Vector3Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3) - { - return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString()); - } - - /// - /// Create a new type by re-arranging the Matrix subchannels. - /// - /// The first subchannel. - /// The second subchannel. - /// The third subchannel. - /// The fourth subchannel. - /// Vector4Node - public Vector4Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4) - { - return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString()); - } - - /// - /// Create a new type by re-arranging the Matrix subchannels. - /// - /// The first subchannel. - /// The second subchannel. - /// The third subchannel. - /// The fourth subchannel. - /// The fifth subchannel. - /// The sixth subchannel. - /// Matrix3x2Node - public Matrix3x2Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4, Subchannel s5, Subchannel s6) - { - return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString(), s5.ToString(), s6.ToString()); - } - - /// - /// Create a new type by re-arranging the Matrix subchannels. - /// - /// The first subchannel. - /// The second subchannel. - /// The third subchannel. - /// The fourth subchannel. - /// The fifth subchannel. - /// The sixth subchannel. - /// The seventh subchannel. - /// The eighth subchannel. - /// The ninth subchannel. - /// The tenth subchannel. - /// The eleventh subchannel. - /// The twelfth subchannel. - /// The thirteenth subchannel. - /// The fourteenth subchannel. - /// The fifteenth subchannel. - /// The sixteenth subchannel. - /// Matrix4x4Node -#pragma warning disable SA1117 // Parameters must be on same line or separate lines - public Matrix4x4Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4, - Subchannel s5, Subchannel s6, Subchannel s7, Subchannel s8, - Subchannel s9, Subchannel s10, Subchannel s11, Subchannel s12, - Subchannel s13, Subchannel s14, Subchannel s15, Subchannel s16) - { - return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString(), - s5.ToString(), s6.ToString(), s7.ToString(), s8.ToString(), - s9.ToString(), s10.ToString(), s11.ToString(), s12.ToString(), - s13.ToString(), s14.ToString(), s15.ToString(), s16.ToString()); - } -#pragma warning restore SA1117 // Parameters must be on same line or separate lines - - /// - /// Gets the value. - /// - /// System.String. - protected internal override string GetValue() - { - return $"Matrix4x4({_value.M11.ToCompositionString()},{_value.M12.ToCompositionString()},{_value.M13.ToCompositionString()},{_value.M14.ToCompositionString()}," + - $"{_value.M21.ToCompositionString()},{_value.M22.ToCompositionString()},{_value.M23.ToCompositionString()},{_value.M24.ToCompositionString()}," + - $"{_value.M31.ToCompositionString()},{_value.M32.ToCompositionString()},{_value.M33.ToCompositionString()},{_value.M34.ToCompositionString()}," + - $"{_value.M41.ToCompositionString()},{_value.M42.ToCompositionString()},{_value.M43.ToCompositionString()},{_value.M44.ToCompositionString()})"; - } - - private Matrix4x4 _value; - - /// - /// Evaluates the current value of the expression - /// - /// The current value of the expression - public Matrix4x4 Evaluate() - { - switch (NodeType) - { - case ExpressionNodeType.ConstantValue: - return _value; - case ExpressionNodeType.ReferenceProperty: - var reference = (Children[0] as ReferenceNode).Reference; - return PropertyName switch - { - nameof(Visual.TransformMatrix) => (reference as Visual).TransformMatrix, - _ => GetProperty() - }; - - Matrix4x4 GetProperty() - { - reference.Properties.TryGetMatrix4x4(PropertyName, out var value); - return value; - } - - case ExpressionNodeType.Add: - return - (Children[0] as Matrix4x4Node).Evaluate() + - (Children[1] as Matrix4x4Node).Evaluate(); - case ExpressionNodeType.Subtract: - return - (Children[0] as Matrix4x4Node).Evaluate() - - (Children[1] as Matrix4x4Node).Evaluate(); - case ExpressionNodeType.Negate: - return - -(Children[0] as Matrix4x4Node).Evaluate(); - case ExpressionNodeType.Multiply: - return (Children[0], Children[1]) switch - { - (Matrix4x4Node v1, Matrix4x4Node v2) => v1.Evaluate() * v2.Evaluate(), - (Matrix4x4Node v1, ScalarNode s2) => v1.Evaluate() * s2.Evaluate(), - (ScalarNode s1, Matrix4x4Node v2) => v2.Evaluate() * s1.Evaluate(), - _ => throw new NotImplementedException() - }; - case ExpressionNodeType.Conditional: - return - (Children[0] as BooleanNode).Evaluate() ? - (Children[1] as Matrix4x4Node).Evaluate() : - (Children[2] as Matrix4x4Node).Evaluate(); - case ExpressionNodeType.Swizzle: - return new Matrix4x4( - Children[0].EvaluateSubchannel(Subchannels[0]), - Children[0].EvaluateSubchannel(Subchannels[1]), - Children[0].EvaluateSubchannel(Subchannels[2]), - Children[0].EvaluateSubchannel(Subchannels[3]), - Children[0].EvaluateSubchannel(Subchannels[4]), - Children[0].EvaluateSubchannel(Subchannels[5]), - Children[0].EvaluateSubchannel(Subchannels[6]), - Children[0].EvaluateSubchannel(Subchannels[7]), - Children[0].EvaluateSubchannel(Subchannels[8]), - Children[0].EvaluateSubchannel(Subchannels[9]), - Children[0].EvaluateSubchannel(Subchannels[10]), - Children[0].EvaluateSubchannel(Subchannels[11]), - Children[0].EvaluateSubchannel(Subchannels[12]), - Children[0].EvaluateSubchannel(Subchannels[13]), - Children[0].EvaluateSubchannel(Subchannels[14]), - Children[0].EvaluateSubchannel(Subchannels[15])); - default: - throw new NotImplementedException(); - } - } - } -#pragma warning restore CS0660, CS0661 -} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/QuaternionNode.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/QuaternionNode.cs deleted file mode 100644 index 9289605a5..000000000 --- a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/QuaternionNode.cs +++ /dev/null @@ -1,198 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Numerics; -using Windows.UI.Composition; - -namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork -{ - // Ignore warning: 'QuaternionNode' defines operator == or operator != but does not override Object.Equals(object o) && Object.GetHashCode() -#pragma warning disable CS0660, CS0661 - /// - /// Class QuaternionNode. This class cannot be inherited. - /// - /// - public sealed class QuaternionNode : ExpressionNode - { - /// - /// Initializes a new instance of the class. - /// - internal QuaternionNode() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The value. - internal QuaternionNode(Quaternion value) - { - _value = value; - NodeType = ExpressionNodeType.ConstantValue; - } - - /// - /// Initializes a new instance of the class. - /// - /// Name of the parameter. - internal QuaternionNode(string paramName) - { - ParamName = paramName; - NodeType = ExpressionNodeType.ConstantParameter; - } - - /// - /// Initializes a new instance of the class. - /// - /// Name of the parameter. - /// The value. - internal QuaternionNode(string paramName, Quaternion value) - { - ParamName = paramName; - _value = value; - NodeType = ExpressionNodeType.ConstantParameter; - - SetQuaternionParameter(paramName, value); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator QuaternionNode(Quaternion value) - { - return new QuaternionNode(value); - } - - /// - /// Implements the * operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static QuaternionNode operator *(QuaternionNode left, ScalarNode right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); - } - - /// - /// Implements the * operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static QuaternionNode operator *(QuaternionNode left, QuaternionNode right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); - } - - /// - /// Implements the / operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static QuaternionNode operator /(QuaternionNode left, QuaternionNode right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Divide, left, right); - } - - /// - /// Implements the == operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static BooleanNode operator ==(QuaternionNode left, QuaternionNode right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Equals, left, right); - } - - /// - /// Implements the != operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static BooleanNode operator !=(QuaternionNode left, QuaternionNode right) - { - return ExpressionFunctions.Function(ExpressionNodeType.NotEquals, left, right); - } - - /// - /// Gets the value. - /// - /// System.String. - protected internal override string GetValue() - { - return $"Quaternion({_value.X.ToCompositionString()},{_value.Y.ToCompositionString()},{_value.Z.ToCompositionString()},{_value.W.ToCompositionString()})"; - } - - private Quaternion _value; - - /// - /// Evaluates the current value of the expression - /// - /// The current value of the expression - public Quaternion Evaluate() - { - switch (NodeType) - { - case ExpressionNodeType.ConstantValue: - return _value; - case ExpressionNodeType.ReferenceProperty: - var reference = (Children[0] as ReferenceNode).Reference; - return PropertyName switch - { - nameof(Visual.Orientation) => (reference as Visual).Orientation, - _ => GetProperty() - }; - - Quaternion GetProperty() - { - reference.Properties.TryGetQuaternion(PropertyName, out var value); - return value; - } - - case ExpressionNodeType.Add: - return - (Children[0] as QuaternionNode).Evaluate() + - (Children[1] as QuaternionNode).Evaluate(); - case ExpressionNodeType.Subtract: - return - (Children[0] as QuaternionNode).Evaluate() - - (Children[1] as QuaternionNode).Evaluate(); - case ExpressionNodeType.Negate: - return - -(Children[0] as QuaternionNode).Evaluate(); - case ExpressionNodeType.Multiply: - return (Children[0], Children[1]) switch - { - (QuaternionNode v1, QuaternionNode v2) => v1.Evaluate() * v2.Evaluate(), - (QuaternionNode v1, ScalarNode s2) => v1.Evaluate() * s2.Evaluate(), - (ScalarNode s1, QuaternionNode v2) => v2.Evaluate() * s1.Evaluate(), - _ => throw new NotImplementedException() - }; - case ExpressionNodeType.Divide: - return - (Children[0] as QuaternionNode).Evaluate() / - (Children[1] as QuaternionNode).Evaluate(); - case ExpressionNodeType.QuaternionFromAxisAngle: - return Quaternion.CreateFromAxisAngle((Children[0] as Vector3Node).Evaluate(), (Children[1] as ScalarNode).Evaluate()); - case ExpressionNodeType.Conditional: - return - (Children[0] as BooleanNode).Evaluate() ? - (Children[1] as QuaternionNode).Evaluate() : - (Children[2] as QuaternionNode).Evaluate(); - case ExpressionNodeType.Swizzle: - return new Quaternion(this.EvaluateSubchannel(Subchannels[0]), this.EvaluateSubchannel(Subchannels[1]), this.EvaluateSubchannel(Subchannels[2]), this.EvaluateSubchannel(Subchannels[4])); - default: - throw new NotImplementedException(); - } - } - } -#pragma warning restore CS0660, CS0661 -} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/ScalarNode.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/ScalarNode.cs deleted file mode 100644 index 394051ed5..000000000 --- a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/ScalarNode.cs +++ /dev/null @@ -1,387 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Numerics; -using Windows.UI.Composition; - -namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork -{ - // Ignore warning: 'ScalarNode' defines operator == or operator != but does not override Object.Equals(object o) && Object.GetHashCode() -#pragma warning disable CS0660, CS0661 - /// - /// Class ScalarNode. This class cannot be inherited. - /// - /// - public sealed class ScalarNode : ExpressionNode - { - /// - /// Initializes a new instance of the class. - /// - internal ScalarNode() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The value. - internal ScalarNode(float value) - { - _value = value; - NodeType = ExpressionNodeType.ConstantValue; - } - - /// - /// Initializes a new instance of the class. - /// - /// Name of the parameter. - internal ScalarNode(string paramName) - { - ParamName = paramName; - NodeType = ExpressionNodeType.ConstantParameter; - } - - /// - /// Initializes a new instance of the class. - /// - /// Name of the parameter. - /// The value. - internal ScalarNode(string paramName, float value) - { - ParamName = paramName; - _value = value; - NodeType = ExpressionNodeType.ConstantParameter; - - SetScalarParameter(paramName, value); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator ScalarNode(float value) - { - return new ScalarNode(value); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator ScalarNode(int value) - { - return new ScalarNode((float)value); - } - - /// - /// Implements the + operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static ScalarNode operator +(ScalarNode left, ScalarNode right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Add, left, right); - } - - /// - /// Implements the - operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static ScalarNode operator -(ScalarNode left, ScalarNode right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Subtract, left, right); - } - - /// - /// Implements the - operator. - /// - /// The value. - /// The result of the operator. - public static ScalarNode operator -(ScalarNode value) - { - return ExpressionFunctions.Function(ExpressionNodeType.Negate, value); - } - - /// - /// Implements the * operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static ScalarNode operator *(ScalarNode left, ScalarNode right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); - } - - /// - /// Implements the * operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static Vector2Node operator *(ScalarNode left, Vector2Node right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); - } - - /// - /// Implements the * operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static Vector3Node operator *(ScalarNode left, Vector3Node right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); - } - - /// - /// Implements the * operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static Vector4Node operator *(ScalarNode left, Vector4Node right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); - } - - /// - /// Implements the * operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static Matrix4x4Node operator *(ScalarNode left, Matrix4x4Node right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); - } - - /// - /// Implements the / operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static ScalarNode operator /(ScalarNode left, ScalarNode right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Divide, left, right); - } - - /// - /// Implements the % operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static ScalarNode operator %(ScalarNode left, ScalarNode right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Modulus, left, right); - } - - /// - /// Implements the == operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static BooleanNode operator ==(ScalarNode left, ScalarNode right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Equals, left, right); - } - - /// - /// Implements the != operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static BooleanNode operator !=(ScalarNode left, ScalarNode right) - { - return ExpressionFunctions.Function(ExpressionNodeType.NotEquals, left, right); - } - - /// - /// Implements the <= operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static BooleanNode operator <=(ScalarNode left, ScalarNode right) - { - return ExpressionFunctions.Function(ExpressionNodeType.LessThanEquals, left, right); - } - - /// - /// Implements the < operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static BooleanNode operator <(ScalarNode left, ScalarNode right) - { - return ExpressionFunctions.Function(ExpressionNodeType.LessThan, left, right); - } - - /// - /// Implements the >= operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static BooleanNode operator >=(ScalarNode left, ScalarNode right) - { - return ExpressionFunctions.Function(ExpressionNodeType.GreaterThanEquals, left, right); - } - - /// - /// Implements the > operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static BooleanNode operator >(ScalarNode left, ScalarNode right) - { - return ExpressionFunctions.Function(ExpressionNodeType.GreaterThan, left, right); - } - - /// - /// Gets the value. - /// - /// System.String. - protected internal override string GetValue() - { - return _value.ToCompositionString(); - } - - private float _value; - - /// - /// Evaluates the current value of the expression - /// - /// The current value of the expression - public float Evaluate() - { - switch (NodeType) - { - case ExpressionNodeType.ConstantValue: - return _value; - case ExpressionNodeType.ReferenceProperty: - var reference = (Children[0] as ReferenceNode).Reference; - return PropertyName switch - { - nameof(Visual.Opacity) => (reference as Visual).Opacity, - nameof(Visual.RotationAngle) => (reference as Visual).RotationAngle, - nameof(InsetClip.BottomInset) => (reference as InsetClip).BottomInset, - nameof(InsetClip.LeftInset) => (reference as InsetClip).LeftInset, - nameof(InsetClip.RightInset) => (reference as InsetClip).RightInset, - nameof(InsetClip.TopInset) => (reference as InsetClip).TopInset, - _ => GetProperty() - }; - - float GetProperty() - { - reference.Properties.TryGetScalar(PropertyName, out var value); - return value; - } - - case ExpressionNodeType.Negate: - return -(Children[0] as ScalarNode).Evaluate(); - case ExpressionNodeType.Add: - return (Children[0] as ScalarNode).Evaluate() + (Children[1] as ScalarNode).Evaluate(); - case ExpressionNodeType.Subtract: - return (Children[0] as ScalarNode).Evaluate() - (Children[1] as ScalarNode).Evaluate(); - case ExpressionNodeType.Multiply: - return (Children[0] as ScalarNode).Evaluate() * (Children[1] as ScalarNode).Evaluate(); - case ExpressionNodeType.Divide: - return (Children[0] as ScalarNode).Evaluate() / (Children[1] as ScalarNode).Evaluate(); - case ExpressionNodeType.Min: - return MathMin((Children[0] as ScalarNode).Evaluate(), (Children[1] as ScalarNode).Evaluate()); - case ExpressionNodeType.Max: - return MathMax((Children[0] as ScalarNode).Evaluate(), (Children[1] as ScalarNode).Evaluate()); - case ExpressionNodeType.Absolute: - return MathAbs((Children[0] as ScalarNode).Evaluate()); - case ExpressionNodeType.Sin: - return MathSin((Children[0] as ScalarNode).Evaluate()); - case ExpressionNodeType.Cos: - return MathCos((Children[0] as ScalarNode).Evaluate()); - case ExpressionNodeType.Asin: - return MathAsin((Children[0] as ScalarNode).Evaluate()); - case ExpressionNodeType.Acos: - return MathAcos((Children[0] as ScalarNode).Evaluate()); - case ExpressionNodeType.Atan: - return MathAtan((Children[0] as ScalarNode).Evaluate()); - case ExpressionNodeType.Ceil: - return MathCeiling((Children[0] as ScalarNode).Evaluate()); - case ExpressionNodeType.Floor: - return MathFloor((Children[0] as ScalarNode).Evaluate()); - case ExpressionNodeType.Ln: - return MathLog((Children[0] as ScalarNode).Evaluate()); - case ExpressionNodeType.Log10: - return MathLog10((Children[0] as ScalarNode).Evaluate()); - case ExpressionNodeType.Pow: - return MathPow((Children[0] as ScalarNode).Evaluate(), (Children[1] as ScalarNode).Evaluate()); - case ExpressionNodeType.Round: - return MathRound((Children[0] as ScalarNode).Evaluate()); - case ExpressionNodeType.Square: - return MathPow((Children[0] as ScalarNode).Evaluate(), 2); - case ExpressionNodeType.Sqrt: - return MathSqrt((Children[0] as ScalarNode).Evaluate()); - case ExpressionNodeType.ToDegrees: - return 180 * (Children[0] as ScalarNode).Evaluate() / MathPI; - case ExpressionNodeType.ToRadians: - return MathPI * (Children[0] as ScalarNode).Evaluate() / 180; - case ExpressionNodeType.Modulus: - return (Children[0] as ScalarNode).Evaluate() % (Children[1] as ScalarNode).Evaluate(); - case ExpressionNodeType.Conditional: - return (Children[0] as BooleanNode).Evaluate() ? (Children[1] as ScalarNode).Evaluate() : (Children[2] as ScalarNode).Evaluate(); - case ExpressionNodeType.Distance: - return Vector2.Distance((Children[0] as Vector2Node).Evaluate(), (Children[1] as Vector2Node).Evaluate()); - case ExpressionNodeType.Clamp: - return Math.Clamp((Children[0] as ScalarNode).Evaluate(), (Children[1] as ScalarNode).Evaluate(), (Children[2] as ScalarNode).Evaluate()); - case ExpressionNodeType.Lerp: - { - var start = (Children[0] as ScalarNode).Evaluate(); - var end = (Children[1] as ScalarNode).Evaluate(); - var progress = (Children[2] as ScalarNode).Evaluate(); - return start + (progress * (end - start)); - } - - case ExpressionNodeType.Swizzle: - return Children[0] switch - { - ScalarNode n => n.Evaluate(), - Vector2Node n => Subchannels[0] switch - { - "X" => n.Evaluate().X, - _ => n.Evaluate().Y, - }, - Vector3Node n => Subchannels[0] switch - { - "X" => n.Evaluate().X, - "Y" => n.Evaluate().Y, - _ => n.Evaluate().Z, - }, - Vector4Node n => Subchannels[0] switch - { - "X" => n.Evaluate().X, - "Y" => n.Evaluate().Y, - "Z" => n.Evaluate().Z, - _ => n.Evaluate().W, - }, - _ => throw new NotImplementedException() - }; - default: - throw new NotImplementedException(); - } - } - } -#pragma warning restore CS0660, CS0661 -} diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/ValueKeywordKind.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/ValueKeywordKind.cs deleted file mode 100644 index f27077d89..000000000 --- a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/ValueKeywordKind.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork -{ - /// - /// Enum ValueKeywordKind - /// - internal enum ValueKeywordKind - { - /// - /// The current value - /// - CurrentValue, - - /// - /// The starting value - /// - StartingValue, - } -} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Vector2Node.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Vector2Node.cs deleted file mode 100644 index 0d186105b..000000000 --- a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Vector2Node.cs +++ /dev/null @@ -1,370 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Numerics; -using Windows.UI.Composition; - -namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork -{ - // Ignore warning: 'Vector2Node' defines operator == or operator != but does not override Object.Equals(object o) && Object.GetHashCode() -#pragma warning disable CS0660, CS0661 - /// - /// Class Vector2Node. This class cannot be inherited. - /// - /// - public sealed class Vector2Node : ExpressionNode - { - /// - /// Initializes a new instance of the class. - /// - internal Vector2Node() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The value. - internal Vector2Node(Vector2 value) - { - _value = value; - NodeType = ExpressionNodeType.ConstantValue; - } - - /// - /// Initializes a new instance of the class. - /// - /// Name of the parameter. - internal Vector2Node(string paramName) - { - ParamName = paramName; - NodeType = ExpressionNodeType.ConstantParameter; - } - - /// - /// Initializes a new instance of the class. - /// - /// Name of the parameter. - /// The value. - internal Vector2Node(string paramName, Vector2 value) - { - ParamName = paramName; - _value = value; - NodeType = ExpressionNodeType.ConstantParameter; - - SetVector2Parameter(paramName, value); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator Vector2Node(Vector2 value) - { - return new Vector2Node(value); - } - - /// - /// Implements the + operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static Vector2Node operator +(Vector2Node left, Vector2Node right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Add, left, right); - } - - /// - /// Implements the - operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static Vector2Node operator -(Vector2Node left, Vector2Node right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Subtract, left, right); - } - - /// - /// Implements the - operator. - /// - /// The value. - /// The result of the operator. - public static Vector2Node operator -(Vector2Node value) - { - return ExpressionFunctions.Function(ExpressionNodeType.Negate, value); - } - - /// - /// Implements the * operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static Vector2Node operator *(Vector2Node left, ScalarNode right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); - } - - /// - /// Implements the * operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static Vector2Node operator *(Vector2Node left, Vector2Node right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); - } - - /// - /// Implements the / operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static Vector2Node operator /(Vector2Node left, Vector2Node right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Divide, left, right); - } - - /// - /// Implements the % operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static Vector2Node operator %(Vector2Node left, Vector2Node right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Modulus, left, right); - } - - /// - /// Implements the == operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static BooleanNode operator ==(Vector2Node left, Vector2Node right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Equals, left, right); - } - - /// - /// Implements the != operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static BooleanNode operator !=(Vector2Node left, Vector2Node right) - { - return ExpressionFunctions.Function(ExpressionNodeType.NotEquals, left, right); - } - - /// - /// Enum Subchannel - /// - public enum Subchannel - { - /// - /// The x channel - /// - X, - - /// - /// The y channel - /// - Y - } - - /// - /// Gets the x subchannel. - /// - /// The x subchannel. - public ScalarNode X - { - get { return GetSubchannels(Subchannel.X); } - } - - /// - /// Gets the y subchannel. - /// - /// The y subchannel. - public ScalarNode Y - { - get { return GetSubchannels(Subchannel.Y); } - } - - /// - /// Create a new type by re-arranging the Vector subchannels. - /// - /// The subchannel - /// ScalarNode - public ScalarNode GetSubchannels(Subchannel s) - { - return SubchannelsInternal(s.ToString()); - } - - /// - /// Create a new type by re-arranging the Vector subchannels. - /// - /// The first subchannel. - /// The second subchannel. - /// Vector2Node. - public Vector2Node GetSubchannels(Subchannel s1, Subchannel s2) - { - return SubchannelsInternal(s1.ToString(), s2.ToString()); - } - - /// - /// Create a new type by re-arranging the Vector subchannels. - /// - /// The first subchannel. - /// The second subchannel. - /// The third subchannel. - /// Vector3Node - public Vector3Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3) - { - return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString()); - } - - /// - /// Create a new type by re-arranging the Vector subchannels. - /// - /// The first subchannel. - /// The second subchannel. - /// The third subchannel. - /// The fourth subchannel. - /// Vector4Node - public Vector4Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4) - { - return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString()); - } - - /// - /// Create a new type by re-arranging the Vector subchannels. - /// - /// The first subchannel. - /// The second subchannel. - /// The third subchannel. - /// The fourth subchannel. - /// The fifth subchannel. - /// The sixth subchannel. - /// Matrix3x2Node - public Matrix3x2Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4, Subchannel s5, Subchannel s6) - { - return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString(), s5.ToString(), s6.ToString()); - } - - /// - /// Create a new type by re-arranging the Vector subchannels. - /// - /// The first subchannel. - /// The second subchannel. - /// The third subchannel. - /// The fourth subchannel. - /// The fifth subchannel. - /// The sixth subchannel. - /// The seventh subchannel. - /// The eighth subchannel. - /// The ninth subchannel. - /// The tenth subchannel. - /// The eleventh subchannel. - /// The twelfth subchannel. - /// The thirteenth subchannel. - /// The fourteenth subchannel. - /// The fifteenth subchannel. - /// The sixteenth subchannel. - /// Matrix4x4Node -#pragma warning disable SA1117 // Parameters must be on same line or separate lines - public Matrix4x4Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4, - Subchannel s5, Subchannel s6, Subchannel s7, Subchannel s8, - Subchannel s9, Subchannel s10, Subchannel s11, Subchannel s12, - Subchannel s13, Subchannel s14, Subchannel s15, Subchannel s16) - { - return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString(), - s5.ToString(), s6.ToString(), s7.ToString(), s8.ToString(), - s9.ToString(), s10.ToString(), s11.ToString(), s12.ToString(), - s13.ToString(), s14.ToString(), s15.ToString(), s16.ToString()); - } -#pragma warning restore SA1117 // Parameters must be on same line or separate lines - - /// - /// Gets the value. - /// - /// System.String. - protected internal override string GetValue() - { - return $"Vector2({_value.X.ToCompositionString()},{_value.Y.ToCompositionString()})"; - } - - private Vector2 _value; - - /// - /// Evaluates the current value of the expression - /// - /// The current value of the expression - public Vector2 Evaluate() - { - switch (NodeType) - { - case ExpressionNodeType.ConstantValue: - return _value; - case ExpressionNodeType.ReferenceProperty: - var reference = (Children[0] as ReferenceNode).Reference; - return PropertyName switch - { - nameof(Visual.Size) => (reference as Visual).Size, - nameof(Visual.AnchorPoint) => (reference as Visual).AnchorPoint, - _ => GetProperty() - }; - - Vector2 GetProperty() - { - reference.Properties.TryGetVector2(PropertyName, out var value); - return value; - } - - case ExpressionNodeType.Conditional: - return - (Children[0] as BooleanNode).Evaluate() ? - (Children[1] as Vector2Node).Evaluate() : - (Children[2] as Vector2Node).Evaluate(); - case ExpressionNodeType.Add: - return - (Children[0] as Vector2Node).Evaluate() + - (Children[1] as Vector2Node).Evaluate(); - case ExpressionNodeType.Subtract: - return - (Children[0] as Vector2Node).Evaluate() - - (Children[1] as Vector2Node).Evaluate(); - case ExpressionNodeType.Negate: - return - -(Children[0] as Vector2Node).Evaluate(); - case ExpressionNodeType.Multiply: - return (Children[0], Children[1]) switch - { - (Vector2Node v1, Vector2Node v2) => v1.Evaluate() * v2.Evaluate(), - (Vector2Node v1, ScalarNode s2) => v1.Evaluate() * s2.Evaluate(), - (ScalarNode s1, Vector2Node v2) => s1.Evaluate() * v2.Evaluate(), - _ => throw new NotImplementedException() - }; - case ExpressionNodeType.Divide: - return - (Children[0] as Vector2Node).Evaluate() / - (Children[1] as Vector2Node).Evaluate(); - case ExpressionNodeType.Vector2: - return new Vector2((Children[0] as ScalarNode).Evaluate(), (Children[1] as ScalarNode).Evaluate()); - case ExpressionNodeType.Swizzle: - return new Vector2(Children[0].EvaluateSubchannel(Subchannels[0]), Children[0].EvaluateSubchannel(Subchannels[1])); - default: - throw new NotImplementedException(); - } - } - } -#pragma warning restore CS0660, CS0661 -} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Vector3Node.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Vector3Node.cs deleted file mode 100644 index 90ee6b07b..000000000 --- a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Vector3Node.cs +++ /dev/null @@ -1,404 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Numerics; -using Windows.UI.Composition; - -namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork -{ - // Ignore warning: 'Vector3Node' defines operator == or operator != but does not override Object.Equals(object o) && Object.GetHashCode() -#pragma warning disable CS0660, CS0661 - /// - /// Class Vector3Node. This class cannot be inherited. - /// - /// - public sealed class Vector3Node : ExpressionNode - { - /// - /// Initializes a new instance of the class. - /// - internal Vector3Node() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The value. - internal Vector3Node(Vector3 value) - { - _value = value; - NodeType = ExpressionNodeType.ConstantValue; - } - - /// - /// Initializes a new instance of the class. - /// - /// Name of the parameter. - internal Vector3Node(string paramName) - { - ParamName = paramName; - NodeType = ExpressionNodeType.ConstantParameter; - } - - /// - /// Initializes a new instance of the class. - /// - /// Name of the parameter. - /// The value. - internal Vector3Node(string paramName, Vector3 value) - { - ParamName = paramName; - _value = value; - NodeType = ExpressionNodeType.ConstantParameter; - - SetVector3Parameter(paramName, value); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator Vector3Node(Vector3 value) - { - return new Vector3Node(value); - } - - /// - /// Implements the + operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static Vector3Node operator +(Vector3Node left, Vector3Node right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Add, left, right); - } - - /// - /// Implements the - operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static Vector3Node operator -(Vector3Node left, Vector3Node right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Subtract, left, right); - } - - /// - /// Implements the - operator. - /// - /// The value. - /// The result of the operator. - public static Vector3Node operator -(Vector3Node value) - { - return ExpressionFunctions.Function(ExpressionNodeType.Negate, value); - } - - /// - /// Implements the * operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static Vector3Node operator *(Vector3Node left, ScalarNode right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); - } - - /// - /// Implements the * operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static Vector3Node operator *(Vector3Node left, Vector3Node right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); - } - - /// - /// Implements the / operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static Vector3Node operator /(Vector3Node left, Vector3Node right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Divide, left, right); - } - - /// - /// Implements the % operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static Vector3Node operator %(Vector3Node left, Vector3Node right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Modulus, left, right); - } - - /// - /// Implements the == operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static BooleanNode operator ==(Vector3Node left, Vector3Node right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Equals, left, right); - } - - /// - /// Implements the != operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static BooleanNode operator !=(Vector3Node left, Vector3Node right) - { - return ExpressionFunctions.Function(ExpressionNodeType.NotEquals, left, right); - } - - /// - /// Enum Subchannel - /// - public enum Subchannel - { - /// - /// The x channel - /// - X, - - /// - /// The y channel - /// - Y, - - /// - /// The z channel - /// - Z - } - - /// - /// Gets the x channel. - /// - /// The x. - public ScalarNode X - { - get { return GetSubchannels(Subchannel.X); } - } - - /// - /// Gets the y channel. - /// - /// The y. - public ScalarNode Y - { - get { return GetSubchannels(Subchannel.Y); } - } - - /// - /// Gets the z channel. - /// - /// The z. - public ScalarNode Z - { - get { return GetSubchannels(Subchannel.Z); } - } - - /// - /// Gets the x and y channel. - /// - /// The xy. - public Vector2Node XY - { - get { return GetSubchannels(Subchannel.X, Subchannel.Y); } - } - - /// - /// Create a new type by re-arranging the Vector subchannels. - /// - /// The subchannel. - /// ScalarNode - public ScalarNode GetSubchannels(Subchannel s) - { - return SubchannelsInternal(s.ToString()); - } - - /// - /// Create a new type by re-arranging the Vector subchannels. - /// - /// The first subchannel. - /// The second subchannel. - /// Vector2Node - public Vector2Node GetSubchannels(Subchannel s1, Subchannel s2) - { - return SubchannelsInternal(s1.ToString(), s2.ToString()); - } - - /// - /// Create a new type by re-arranging the Vector subchannels. - /// - /// The first subchannel. - /// The second subchannel. - /// The third subchannel. - /// Vector3Node - public Vector3Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3) - { - return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString()); - } - - /// - /// Create a new type by re-arranging the Vector subchannels. - /// - /// The first subchannel. - /// The second subchannel. - /// The third subchannel. - /// The fourth subchannel. - /// Vector4Node - public Vector4Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4) - { - return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString()); - } - - /// - /// Create a new type by re-arranging the Vector subchannels. - /// - /// The first subchannel. - /// The second subchannel. - /// The third subchannel. - /// The fourth subchannel. - /// The fifth subchannel. - /// The sixth subchannel. - /// Matrix3x2Node - public Matrix3x2Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4, Subchannel s5, Subchannel s6) - { - return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString(), s5.ToString(), s6.ToString()); - } - - /// - /// Create a new type by re-arranging the Vector subchannels. - /// - /// The first subchannel. - /// The second subchannel. - /// The third subchannel. - /// The fourth subchannel. - /// The fifth subchannel. - /// The sixth subchannel. - /// The seventh subchannel. - /// The eighth subchannel. - /// The ninth subchannel. - /// The tenth subchannel. - /// The eleventh subchannel. - /// The twelfth subchannel. - /// The thirteenth subchannel. - /// The fourteenth subchannel. - /// The fifteenth subchannel. - /// The sixteenth subchannel. - /// Matrix4x4Node -#pragma warning disable SA1117 // Parameters must be on same line or separate lines - public Matrix4x4Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4, - Subchannel s5, Subchannel s6, Subchannel s7, Subchannel s8, - Subchannel s9, Subchannel s10, Subchannel s11, Subchannel s12, - Subchannel s13, Subchannel s14, Subchannel s15, Subchannel s16) - { - return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString(), - s5.ToString(), s6.ToString(), s7.ToString(), s8.ToString(), - s9.ToString(), s10.ToString(), s11.ToString(), s12.ToString(), - s13.ToString(), s14.ToString(), s15.ToString(), s16.ToString()); - } -#pragma warning restore SA1117 // Parameters must be on same line or separate lines - - /// - /// Gets the value. - /// - /// System.String. - protected internal override string GetValue() - { - return $"Vector3({_value.X.ToCompositionString()},{_value.Y.ToCompositionString()},{_value.Z.ToCompositionString()})"; - } - - private Vector3 _value; - - /// - /// Evaluates the current value of the expression - /// - /// The current value of the expression - public Vector3 Evaluate() - { - switch (NodeType) - { - case ExpressionNodeType.ConstantValue: - return _value; - case ExpressionNodeType.ReferenceProperty: - var reference = (Children[0] as ReferenceNode).Reference; - return PropertyName switch - { - nameof(Visual.Offset) => (reference as Visual).Offset, - nameof(Visual.RotationAxis) => (reference as Visual).RotationAxis, - nameof(Visual.CenterPoint) => (reference as Visual).CenterPoint, - _ => GetProperty() - }; - - Vector3 GetProperty() - { - reference.Properties.TryGetVector3(PropertyName, out var value); - return value; - } - - case ExpressionNodeType.Conditional: - return - (Children[0] as BooleanNode).Evaluate() ? - (Children[1] as Vector3Node).Evaluate() : - (Children[2] as Vector3Node).Evaluate(); - case ExpressionNodeType.Add: - return - (Children[0] as Vector3Node).Evaluate() + - (Children[1] as Vector3Node).Evaluate(); - case ExpressionNodeType.Subtract: - return - (Children[0] as Vector3Node).Evaluate() - - (Children[1] as Vector3Node).Evaluate(); - case ExpressionNodeType.Lerp: - { - var t = (Children[2] as ScalarNode).Evaluate(); - return - (Children[0] as Vector3Node).Evaluate() * t - - (Children[1] as Vector3Node).Evaluate() * (1 - t); - } - case ExpressionNodeType.Negate: - return - -(Children[0] as Vector3Node).Evaluate(); - case ExpressionNodeType.Multiply: - return (Children[0], Children[1]) switch - { - (Vector3Node v1, Vector3Node v2) => v1.Evaluate() * v2.Evaluate(), - (Vector3Node v1, ScalarNode s2) => v1.Evaluate() * s2.Evaluate(), - (ScalarNode s1, Vector3Node v2) => s1.Evaluate() * v2.Evaluate(), - _ => throw new NotImplementedException() - }; - case ExpressionNodeType.Divide: - return - (Children[0] as Vector3Node).Evaluate() / - (Children[1] as Vector3Node).Evaluate(); - case ExpressionNodeType.Vector3: - return new Vector3( - (Children[0] as ScalarNode).Evaluate(), - (Children[1] as ScalarNode).Evaluate(), - (Children[2] as ScalarNode).Evaluate()); - case ExpressionNodeType.Swizzle: - return new Vector3(Children[0].EvaluateSubchannel(Subchannels[0]), Children[0].EvaluateSubchannel(Subchannels[1]), Children[0].EvaluateSubchannel(Subchannels[2])); - default: - throw new NotImplementedException(); - } - } - } -#pragma warning restore CS0660, CS0661 -} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Vector4Node.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Vector4Node.cs deleted file mode 100644 index 4f9189722..000000000 --- a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionNodes/Vector4Node.cs +++ /dev/null @@ -1,421 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Numerics; -using Windows.UI.Composition; - -namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork -{ - // Ignore warning: 'Vector4Node' defines operator == or operator != but does not override Object.Equals(object o) && Object.GetHashCode() -#pragma warning disable CS0660, CS0661 - /// - /// Class Vector4Node. This class cannot be inherited. - /// - /// - public sealed class Vector4Node : ExpressionNode - { - /// - /// Initializes a new instance of the class. - /// - internal Vector4Node() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The value. - internal Vector4Node(Vector4 value) - { - _value = value; - NodeType = ExpressionNodeType.ConstantValue; - } - - /// - /// Initializes a new instance of the class. - /// - /// Name of the parameter. - internal Vector4Node(string paramName) - { - ParamName = paramName; - NodeType = ExpressionNodeType.ConstantParameter; - } - - /// - /// Initializes a new instance of the class. - /// - /// Name of the parameter. - /// The value. - internal Vector4Node(string paramName, Vector4 value) - { - ParamName = paramName; - _value = value; - NodeType = ExpressionNodeType.ConstantParameter; - - SetVector4Parameter(paramName, value); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator Vector4Node(Vector4 value) - { - return new Vector4Node(value); - } - - /// - /// Implements the + operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static Vector4Node operator +(Vector4Node left, Vector4Node right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Add, left, right); - } - - /// - /// Implements the - operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static Vector4Node operator -(Vector4Node left, Vector4Node right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Subtract, left, right); - } - - /// - /// Implements the - operator. - /// - /// The value. - /// The result of the operator. - public static Vector4Node operator -(Vector4Node value) - { - return ExpressionFunctions.Function(ExpressionNodeType.Negate, value); - } - - /// - /// Implements the * operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static Vector4Node operator *(Vector4Node left, ScalarNode right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); - } - - /// - /// Implements the * operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static Vector4Node operator *(Vector4Node left, Vector4Node right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Multiply, left, right); - } - - /// - /// Implements the / operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static Vector4Node operator /(Vector4Node left, Vector4Node right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Divide, left, right); - } - - /// - /// Implements the % operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static Vector4Node operator %(Vector4Node left, Vector4Node right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Modulus, left, right); - } - - /// - /// Implements the == operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static BooleanNode operator ==(Vector4Node left, Vector4Node right) - { - return ExpressionFunctions.Function(ExpressionNodeType.Equals, left, right); - } - - /// - /// Implements the != operator. - /// - /// The left. - /// The right. - /// The result of the operator. - public static BooleanNode operator !=(Vector4Node left, Vector4Node right) - { - return ExpressionFunctions.Function(ExpressionNodeType.NotEquals, left, right); - } - - /// - /// Enum Subchannel - /// - public enum Subchannel - { - /// - /// The x channel - /// - X, - - /// - /// The y channel - /// - Y, - - /// - /// The z channel - /// - Z, - - /// - /// The w channel - /// - W - } - - /// - /// Gets the x channel. - /// - /// The x. - public ScalarNode X - { - get { return GetSubchannels(Subchannel.X); } - } - - /// - /// Gets the y channel. - /// - /// The y. - public ScalarNode Y - { - get { return GetSubchannels(Subchannel.Y); } - } - - /// - /// Gets the z channel. - /// - /// The z. - public ScalarNode Z - { - get { return GetSubchannels(Subchannel.Z); } - } - - /// - /// Gets the w channel. - /// - /// The w. - public ScalarNode W - { - get { return GetSubchannels(Subchannel.W); } - } - - /// - /// Gets the x and y channels. - /// - /// The xy. - public Vector2Node XY - { - get { return GetSubchannels(Subchannel.X, Subchannel.Y); } - } - - /// - /// Gets the x, y, and z channels. - /// - /// The xyz. - public Vector3Node XYZ - { - get { return GetSubchannels(Subchannel.X, Subchannel.Y, Subchannel.Z); } - } - - /// - /// Create a new type by re-arranging the Vector subchannels. - /// - /// The subchannel. - /// ScalarNode - public ScalarNode GetSubchannels(Subchannel s) - { - return SubchannelsInternal(s.ToString()); - } - - /// - /// Create a new type by re-arranging the Vector subchannels. - /// - /// The first subchannel. - /// The second subchannel. - /// Vector2Node - public Vector2Node GetSubchannels(Subchannel s1, Subchannel s2) - { - return SubchannelsInternal(s1.ToString(), s2.ToString()); - } - - /// - /// Create a new type by re-arranging the Vector subchannels. - /// - /// The first subchannel. - /// The second subchannel. - /// The third subchannel. - /// Vector3Node - public Vector3Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3) - { - return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString()); - } - - /// - /// Create a new type by re-arranging the Vector subchannels. - /// - /// The first subchannel. - /// The second subchannel. - /// The third subchannel. - /// The fourth subchannel. - /// Vector4Node - public Vector4Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4) - { - return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString()); - } - - /// - /// Create a new type by re-arranging the Vector subchannels. - /// - /// The first subchannel. - /// The second subchannel. - /// The third subchannel. - /// The fourth subchannel. - /// The fifth subchannel. - /// The sixth subchannel. - /// Matrix3x2Node - public Matrix3x2Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4, Subchannel s5, Subchannel s6) - { - return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString(), s5.ToString(), s6.ToString()); - } - - /// - /// Create a new type by re-arranging the Vector subchannels. - /// - /// The first subchannel. - /// The second subchannel. - /// The third subchannel. - /// The fourth subchannel. - /// The fifth subchannel. - /// The sixth subchannel. - /// The seventh subchannel. - /// The eighth subchannel. - /// The ninth subchannel. - /// The tenth subchannel. - /// The eleventh subchannel. - /// The twelfth subchannel. - /// The thirteenth subchannel. - /// The fourteenth subchannel. - /// The fifteenth subchannel. - /// The sixteenth subchannel. - /// Matrix4x4Node -#pragma warning disable SA1117 // Parameters must be on same line or separate lines - public Matrix4x4Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4, - Subchannel s5, Subchannel s6, Subchannel s7, Subchannel s8, - Subchannel s9, Subchannel s10, Subchannel s11, Subchannel s12, - Subchannel s13, Subchannel s14, Subchannel s15, Subchannel s16) - { - return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString(), - s5.ToString(), s6.ToString(), s7.ToString(), s8.ToString(), - s9.ToString(), s10.ToString(), s11.ToString(), s12.ToString(), - s13.ToString(), s14.ToString(), s15.ToString(), s16.ToString()); - } -#pragma warning restore SA1117 // Parameters must be on same line or separate lines - - /// - /// Gets the value. - /// - /// System.String. - protected internal override string GetValue() - { - return $"Vector4({_value.X.ToCompositionString()},{_value.Y.ToCompositionString()},{_value.Z.ToCompositionString()},{_value.W.ToCompositionString()})"; - } - - private Vector4 _value; - - /// - /// Evaluates the current value of the expression - /// - /// The current value of the expression - public Vector4 Evaluate() - { - switch (NodeType) - { - case ExpressionNodeType.ConstantParameter: - throw new NotImplementedException(); - case ExpressionNodeType.ReferenceProperty: - var reference = (Children[0] as ReferenceNode).Reference; - return PropertyName switch - { - _ => GetProperty() - }; - - Vector4 GetProperty() - { - reference.Properties.TryGetVector4(PropertyName, out var value); - return value; - } - - case ExpressionNodeType.Conditional: - return - (Children[0] as BooleanNode).Evaluate() ? - (Children[1] as Vector4Node).Evaluate() : - (Children[2] as Vector4Node).Evaluate(); - case ExpressionNodeType.Add: - return - (Children[0] as Vector4Node).Evaluate() + - (Children[1] as Vector4Node).Evaluate(); - case ExpressionNodeType.Subtract: - return - (Children[0] as Vector4Node).Evaluate() - - (Children[1] as Vector4Node).Evaluate(); - case ExpressionNodeType.Negate: - return - -(Children[0] as Vector4Node).Evaluate(); - case ExpressionNodeType.Transform: - return - Vector4.Transform((Children[0] as Vector4Node).Evaluate(), (Children[1] as Matrix4x4Node).Evaluate()); - case ExpressionNodeType.Multiply: - return (Children[0], Children[1]) switch - { - (Vector4Node v1, Vector4Node v2) => v1.Evaluate() * v2.Evaluate(), - (Vector4Node v1, ScalarNode s2) => v1.Evaluate() * s2.Evaluate(), - (ScalarNode s1, Vector4Node v2) => s1.Evaluate() * v2.Evaluate(), - _ => throw new NotImplementedException() - }; - case ExpressionNodeType.Divide: - return - (Children[0] as Vector4Node).Evaluate() / - (Children[1] as Vector4Node).Evaluate(); - case ExpressionNodeType.Vector4: - return new Vector4( - (Children[0] as ScalarNode).Evaluate(), - (Children[1] as ScalarNode).Evaluate(), - (Children[2] as ScalarNode).Evaluate(), - (Children[2] as ScalarNode).Evaluate()); - case ExpressionNodeType.Swizzle: - return new Vector4(Children[0].EvaluateSubchannel(Subchannels[0]), Children[0].EvaluateSubchannel(Subchannels[1]), Children[0].EvaluateSubchannel(Subchannels[2]), Children[0].EvaluateSubchannel(Subchannels[3])); - default: - throw new NotImplementedException(); - } - } - } -#pragma warning restore CS0660, CS0661 -} diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionValues/ExpressionValues.Constant.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionValues/ExpressionValues.Constant.cs deleted file mode 100644 index e56d2cfcc..000000000 --- a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionValues/ExpressionValues.Constant.cs +++ /dev/null @@ -1,216 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Numerics; -using Windows.UI; - -namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork -{ - // ExpressionValues is a static class instead of a namespace to improve intellisense discoverablity and consistency with the other helper classes. - - /// - /// Class ExpressionValues. - /// - public static partial class ExpressionValues - { - /// - /// Create a constant parameter whose value can be changed without recreating the expression. - /// - public static class Constant - { - // Constant parameters with no default value - - /// - /// Creates a named constant parameter of type bool. - /// - /// The name that will be used to refer to the parameter at a later time. - /// BooleanNode - public static BooleanNode CreateConstantBoolean(string paramName) - { - return new BooleanNode(paramName); - } - - /// - /// Creates a named constant parameter of type float. - /// - /// The name that will be used to refer to the parameter at a later time. - /// ScalarNode. - public static ScalarNode CreateConstantScalar(string paramName) - { - return new ScalarNode(paramName); - } - - /// - /// Creates a named constant parameter of type Vector2. - /// - /// The name that will be used to refer to the parameter at a later time. - /// Vector2Node. - public static Vector2Node CreateConstantVector2(string paramName) - { - return new Vector2Node(paramName); - } - - /// - /// Creates a named constant parameter of type Vector3. - /// - /// The name that will be used to refer to the parameter at a later time. - /// Vector3Node. - public static Vector3Node CreateConstantVector3(string paramName) - { - return new Vector3Node(paramName); - } - - /// - /// Creates a named constant parameter of type Vector4. - /// - /// The name that will be used to refer to the parameter at a later time. - /// Vector4Node. - public static Vector4Node CreateConstantVector4(string paramName) - { - return new Vector4Node(paramName); - } - - /// - /// Creates a named constant parameter of type Color. - /// - /// The name that will be used to refer to the parameter at a later time. - /// ColorNode. - public static ColorNode CreateConstantColor(string paramName) - { - return new ColorNode(paramName); - } - - /// - /// Creates a named constant parameter of type Quaternion. - /// - /// The name that will be used to refer to the parameter at a later time. - /// QuaternionNode. - public static QuaternionNode CreateConstantQuaternion(string paramName) - { - return new QuaternionNode(paramName); - } - - /// - /// Creates a named constant parameter of type Matrix3x2. - /// - /// The name that will be used to refer to the parameter at a later time. - /// Matrix3x2Node. - public static Matrix3x2Node CreateConstantMatrix3x2(string paramName) - { - return new Matrix3x2Node(paramName); - } - - /// - /// Creates a named constant parameter of type Matrix4x4. - /// - /// The name that will be used to refer to the parameter at a later time. - /// Matrix4x4Node. - public static Matrix4x4Node CreateConstantMatrix4x4(string paramName) - { - return new Matrix4x4Node(paramName); - } - - // Constant parameters with a default value - - /// - /// Creates a named constant parameter of type bool, initialized with the specified value. - /// - /// The name that will be used to refer to the parameter at a later time. - /// The value of the parameter. - /// BooleanNode. - public static BooleanNode CreateConstantBoolean(string paramName, bool value) - { - return new BooleanNode(paramName, value); - } - - /// - /// Creates a named constant parameter of type float, initialized with the specified value. - /// - /// The name that will be used to refer to the parameter at a later time. - /// The value of the parameter. - /// ScalarNode. - public static ScalarNode CreateConstantScalar(string paramName, float value) - { - return new ScalarNode(paramName, value); - } - - /// - /// Creates a named constant parameter of type Vector2, initialized with the specified value. - /// - /// The name that will be used to refer to the parameter at a later time. - /// The value of the parameter. - /// Vector2Node. - public static Vector2Node CreateConstantVector2(string paramName, Vector2 value) - { - return new Vector2Node(paramName, value); - } - - /// - /// Creates a named constant parameter of type Vector3, initialized with the specified value. - /// - /// The name that will be used to refer to the parameter at a later time. - /// The value of the parameter. - /// Vector3Node. - public static Vector3Node CreateConstantVector3(string paramName, Vector3 value) - { - return new Vector3Node(paramName, value); - } - - /// - /// Creates a named constant parameter of type Vector4, initialized with the specified value. - /// - /// The name that will be used to refer to the parameter at a later time. - /// The value of the parameter. - /// Vector4Node. - public static Vector4Node CreateConstantVector4(string paramName, Vector4 value) - { - return new Vector4Node(paramName, value); - } - - /// - /// Creates a named constant parameter of type Color, initialized with the specified value. - /// - /// The name that will be used to refer to the parameter at a later time. - /// The value of the parameter. - /// ColorNode. - public static ColorNode CreateConstantColor(string paramName, Color value) - { - return new ColorNode(paramName, value); - } - - /// - /// Creates a named constant parameter of type Quaternion, initialized with the specified value. - /// - /// The name that will be used to refer to the parameter at a later time. - /// The value of the parameter. - /// QuaternionNode. - public static QuaternionNode CreateConstantQuaternion(string paramName, Quaternion value) - { - return new QuaternionNode(paramName, value); - } - - /// - /// Creates a named constant parameter of type Matrix3x2, initialized with the specified value. - /// - /// The name that will be used to refer to the parameter at a later time. - /// The value of the parameter. - /// Matrix3x2Node. - public static Matrix3x2Node CreateConstantMatrix3x2(string paramName, Matrix3x2 value) - { - return new Matrix3x2Node(paramName, value); - } - - /// - /// Creates a named constant parameter of type Matrix4x4, initialized with the specified value. - /// - /// The name that will be used to refer to the parameter at a later time. - /// The value of the parameter. - /// Matrix4x4Node. - public static Matrix4x4Node CreateConstantMatrix4x4(string paramName, Matrix4x4 value) - { - return new Matrix4x4Node(paramName, value); - } - } - } -} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionValues/ExpressionValues.CurrentValue.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionValues/ExpressionValues.CurrentValue.cs deleted file mode 100644 index e6a5ce346..000000000 --- a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionValues/ExpressionValues.CurrentValue.cs +++ /dev/null @@ -1,101 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork -{ - // ExpressionValues is a static class instead of a namespace to improve intellisense discoverablity and consistency with the other helper classes. - - /// - /// Class ExpressionValues. - /// - public static partial class ExpressionValues - { - /// - /// Refer to the current value of the property this expression is connected to. - /// - public static class CurrentValue - { - /// - /// Create a reference to the current value of the boolean property that this expression will be connected to. - /// - /// BooleanNode. - public static BooleanNode CreateBooleanCurrentValue() - { - return ExpressionNode.CreateValueKeyword(ValueKeywordKind.CurrentValue); - } - - /// - /// Create a reference to the current value of the float property that this expression will be connected to. - /// - /// ScalarNode. - public static ScalarNode CreateScalarCurrentValue() - { - return ExpressionNode.CreateValueKeyword(ValueKeywordKind.CurrentValue); - } - - /// - /// Create a reference to the current value of the Vector2 property that this expression will be connected to. - /// - /// Vector2Node. - public static Vector2Node CreateVector2CurrentValue() - { - return ExpressionNode.CreateValueKeyword(ValueKeywordKind.CurrentValue); - } - - /// - /// Create a reference to the current value of the Vector3 property that this expression will be connected to. - /// - /// Vector3Node. - public static Vector3Node CreateVector3CurrentValue() - { - return ExpressionNode.CreateValueKeyword(ValueKeywordKind.CurrentValue); - } - - /// - /// Create a reference to the current value of the Vector4 property that this expression will be connected to. - /// - /// Vector4Node. - public static Vector4Node CreateVector4CurrentValue() - { - return ExpressionNode.CreateValueKeyword(ValueKeywordKind.CurrentValue); - } - - /// - /// Create a reference to the current value of the Color property that this expression will be connected to. - /// - /// ColorNode. - public static ColorNode CreateColorCurrentValue() - { - return ExpressionNode.CreateValueKeyword(ValueKeywordKind.CurrentValue); - } - - /// - /// Create a reference to the current value of the Quaternion property that this expression will be connected to. - /// - /// QuaternionNode. - public static QuaternionNode CreateQuaternionCurrentValue() - { - return ExpressionNode.CreateValueKeyword(ValueKeywordKind.CurrentValue); - } - - /// - /// Create a reference to the current value of the Matrix3x2 property that this expression will be connected to. - /// - /// Matrix3x2Node. - public static Matrix3x2Node CreateMatrix3x2CurrentValue() - { - return ExpressionNode.CreateValueKeyword(ValueKeywordKind.CurrentValue); - } - - /// - /// Create a reference to the current value of the Matrix4x4 property that this expression will be connected to. - /// - /// Matrix4x4Node. - public static Matrix4x4Node CreateMatrix4x4CurrentValue() - { - return ExpressionNode.CreateValueKeyword(ValueKeywordKind.CurrentValue); - } - } - } -} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionValues/ExpressionValues.Reference.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionValues/ExpressionValues.Reference.cs deleted file mode 100644 index 018d77dee..000000000 --- a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionValues/ExpressionValues.Reference.cs +++ /dev/null @@ -1,140 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork -{ - // ExpressionValues is a static class instead of a namespace to improve intellisense discoverablity and consistency with the other helper classes. - - /// - /// Class ExpressionValues. - /// - public static partial class ExpressionValues - { - /// - /// Create a reference to a CompositionObject. - /// - public static class Reference - { - /// - /// Creates a named reference parameter to an AmbientLight. - /// - /// The name that will be used to refer to the parameter at a later time. - /// AmbientLightReferenceNode. - public static AmbientLightReferenceNode CreateAmbientLightReference(string parameterName) - { - return new AmbientLightReferenceNode(parameterName); - } - - /// - /// Creates a named reference parameter to a ColorBrush. - /// - /// The name that will be used to refer to the parameter at a later time. - /// ColorBrushReferenceNode. - public static ColorBrushReferenceNode CreateColorBrushReference(string parameterName) - { - return new ColorBrushReferenceNode(parameterName); - } - - /// - /// Creates a named reference parameter to a DistantLight. - /// - /// The name that will be used to refer to the parameter at a later time. - /// DistantLightReferenceNode. - public static DistantLightReferenceNode CreateDistantLightReference(string parameterName) - { - return new DistantLightReferenceNode(parameterName); - } - - /// - /// Creates a named reference parameter to a DropShadow. - /// - /// The name that will be used to refer to the parameter at a later time. - /// DropShadowReferenceNode. - public static DropShadowReferenceNode CreateDropShadowReference(string parameterName) - { - return new DropShadowReferenceNode(parameterName); - } - - /// - /// Creates a named reference parameter to an InsetClip. - /// - /// The name that will be used to refer to the parameter at a later time. - /// InsetClipReferenceNode. - public static InsetClipReferenceNode CreateInsetClipReference(string parameterName) - { - return new InsetClipReferenceNode(parameterName); - } - - /// - /// Creates a named reference parameter to an InteractionTracker. - /// - /// The name that will be used to refer to the parameter at a later time. - /// InteractionTrackerReferenceNode. - public static InteractionTrackerReferenceNode CreateInteractionTrackerReference(string parameterName) - { - return new InteractionTrackerReferenceNode(parameterName); - } - - /// - /// Creates a named reference parameter to a NineGridBrush. - /// - /// The name that will be used to refer to the parameter at a later time. - /// NineGridBrushReferenceNode. - public static NineGridBrushReferenceNode CreateNineGridBrushReference(string parameterName) - { - return new NineGridBrushReferenceNode(parameterName); - } - - /// - /// Creates a named reference parameter to a PointLight. - /// - /// The name that will be used to refer to the parameter at a later time. - /// PointLightReferenceNode. - public static PointLightReferenceNode CreatePointLightReference(string parameterName) - { - return new PointLightReferenceNode(parameterName); - } - - /// - /// Creates a named reference parameter to a PropertySet. - /// - /// The name that will be used to refer to the parameter at a later time. - /// PropertySetReferenceNode. - public static PropertySetReferenceNode CreatePropertySetReference(string parameterName) - { - return new PropertySetReferenceNode(parameterName); - } - - /// - /// Creates a named reference parameter to a SpotLight. - /// - /// The name that will be used to refer to the parameter at a later time. - /// SpotLightReferenceNode. - public static SpotLightReferenceNode CreateSpotLightReference(string parameterName) - { - return new SpotLightReferenceNode(parameterName); - } - - /// - /// Creates a named reference parameter to a SurfaceBrush. - /// - /// The name that will be used to refer to the parameter at a later time. - /// SurfaceBrushReferenceNode. - public static SurfaceBrushReferenceNode CreateSurfaceBrushReference(string parameterName) - { - return new SurfaceBrushReferenceNode(parameterName); - } - - /// - /// Creates a named reference parameter to a Visual. - /// - /// The name that will be used to refer to the parameter at a later time. - /// VisualReferenceNode. - public static VisualReferenceNode CreateVisualReference(string parameterName) - { - return new VisualReferenceNode(parameterName); - } - } - } -} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionValues/ExpressionValues.StartingValue.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionValues/ExpressionValues.StartingValue.cs deleted file mode 100644 index 99d932e5c..000000000 --- a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionValues/ExpressionValues.StartingValue.cs +++ /dev/null @@ -1,101 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork -{ - // ExpressionValues is a static class instead of a namespace to improve intellisense discoverablity and consistency with the other helper classes. - - /// - /// Class ExpressionValues. - /// - public static partial class ExpressionValues - { - /// - /// Refer to the value of the property this expression is connected to, sampled during the first frame of execution. - /// - public static class StartingValue - { - /// - /// Create a reference to the starting value of the boolean property that this expression will be connected to. - /// - /// BooleanNode. - public static BooleanNode CreateBooleanStartingValue() - { - return ExpressionNode.CreateValueKeyword(ValueKeywordKind.StartingValue); - } - - /// - /// Create a reference to the starting value of the float property that this expression will be connected to. - /// - /// ScalarNode. - public static ScalarNode CreateScalarStartingValue() - { - return ExpressionNode.CreateValueKeyword(ValueKeywordKind.StartingValue); - } - - /// - /// Create a reference to the starting value of the Vector2 property that this expression will be connected to. - /// - /// Vector2Node. - public static Vector2Node CreateVector2StartingValue() - { - return ExpressionNode.CreateValueKeyword(ValueKeywordKind.StartingValue); - } - - /// - /// Create a reference to the starting value of the Vector3 property that this expression will be connected to. - /// - /// Vector3Node. - public static Vector3Node CreateVector3StartingValue() - { - return ExpressionNode.CreateValueKeyword(ValueKeywordKind.StartingValue); - } - - /// - /// Create a reference to the starting value of the Vector4 property that this expression will be connected to. - /// - /// Vector4Node. - public static Vector4Node CreateVector4StartingValue() - { - return ExpressionNode.CreateValueKeyword(ValueKeywordKind.StartingValue); - } - - /// - /// Create a reference to the starting value of the Color property that this expression will be connected to. - /// - /// ColorNode. - public static ColorNode CreateColorStartingValue() - { - return ExpressionNode.CreateValueKeyword(ValueKeywordKind.StartingValue); - } - - /// - /// Create a reference to the starting value of the Quaternion property that this expression will be connected to. - /// - /// QuaternionNode. - public static QuaternionNode CreateQuaternionStartingValue() - { - return ExpressionNode.CreateValueKeyword(ValueKeywordKind.StartingValue); - } - - /// - /// Create a reference to the starting value of the Matrix3x2 property that this expression will be connected to. - /// - /// Matrix3x2Node. - public static Matrix3x2Node CreateMatrix3x2StartingValue() - { - return ExpressionNode.CreateValueKeyword(ValueKeywordKind.StartingValue); - } - - /// - /// Create a reference to the starting value of the Matrix4x4 property that this expression will be connected to. - /// - /// Matrix4x4Node. - public static Matrix4x4Node CreateMatrix4x4StartingValue() - { - return ExpressionNode.CreateValueKeyword(ValueKeywordKind.StartingValue); - } - } - } -} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionValues/ExpressionValues.Target.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionValues/ExpressionValues.Target.cs deleted file mode 100644 index b51d7f754..000000000 --- a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ExpressionValues/ExpressionValues.Target.cs +++ /dev/null @@ -1,128 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork -{ - // ExpressionValues is a static class instead of a namespace to improve intellisense discoverablity and consistency with the other helper classes. - - /// - /// Class ExpressionValues. - /// - public static partial class ExpressionValues - { - /// - /// Create a reference to the CompositionObject this expression will be connected to. - /// - public static class Target - { - /// - /// Create a reference to the AmbientLight target that this expression will be connected to. - /// - /// AmbientLightReferenceNode. - public static AmbientLightReferenceNode CreateAmbientLightTarget() - { - return AmbientLightReferenceNode.CreateTargetReference(); - } - - /// - /// Create a reference to the ColorBrush target that this expression will be connected to. - /// - /// ColorBrushReferenceNode. - public static ColorBrushReferenceNode CreateColorBrushTarget() - { - return ColorBrushReferenceNode.CreateTargetReference(); - } - - /// - /// Create a reference to the DistantLight target that this expression will be connected to. - /// - /// DistantLightReferenceNode. - public static DistantLightReferenceNode CreateDistantLightTarget() - { - return DistantLightReferenceNode.CreateTargetReference(); - } - - /// - /// Create a reference to the DropShadow target that this expression will be connected to. - /// - /// DropShadowReferenceNode. - public static DropShadowReferenceNode CreateDropShadowTarget() - { - return DropShadowReferenceNode.CreateTargetReference(); - } - - /// - /// Create a reference to the InsetClip target that this expression will be connected to. - /// - /// InsetClipReferenceNode. - public static InsetClipReferenceNode CreateInsetClipTarget() - { - return InsetClipReferenceNode.CreateTargetReference(); - } - - /// - /// Create a reference to the InteractionTracker target that this expression will be connected to. - /// - /// InteractionTrackerReferenceNode. - public static InteractionTrackerReferenceNode CreateInteractionTrackerTarget() - { - return InteractionTrackerReferenceNode.CreateTargetReference(); - } - - /// - /// Create a reference to the NineGridBrush target that this expression will be connected to. - /// - /// NineGridBrushReferenceNode. - public static NineGridBrushReferenceNode CreateNineGridBrushTarget() - { - return NineGridBrushReferenceNode.CreateTargetReference(); - } - - /// - /// Create a reference to the PointLight target that this expression will be connected to. - /// - /// PointLightReferenceNode. - public static PointLightReferenceNode CreatePointLightTarget() - { - return PointLightReferenceNode.CreateTargetReference(); - } - - /// - /// Create a reference to the PropertySet target that this expression will be connected to. - /// - /// PropertySetReferenceNode. - public static PropertySetReferenceNode CreatePropertySetTarget() - { - return PropertySetReferenceNode.CreateTargetReference(); - } - - /// - /// Create a reference to the SpotLight target that this expression will be connected to. - /// - /// SpotLightReferenceNode. - public static SpotLightReferenceNode CreateSpotLightTarget() - { - return SpotLightReferenceNode.CreateTargetReference(); - } - - /// - /// Create a reference to the SurfaceBrush target that this expression will be connected to. - /// - /// SurfaceBrushReferenceNode. - public static SurfaceBrushReferenceNode CreateSurfaceBrushTarget() - { - return SurfaceBrushReferenceNode.CreateTargetReference(); - } - - /// - /// Create a reference to the Visual target that this expression will be connected to. - /// - /// VisualReferenceNode. - public static VisualReferenceNode CreateVisualTarget() - { - return VisualReferenceNode.CreateTargetReference(); - } - } - } -} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/FloatExtensions.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/FloatExtensions.cs deleted file mode 100644 index 2f22295af..000000000 --- a/labs/CompositionCollectionView/ExpressionsFork/Expressions/FloatExtensions.cs +++ /dev/null @@ -1,48 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Diagnostics.Contracts; - -namespace Microsoft.Toolkit.Uwp.UI.Animations -{ - /// - /// An extension for the type - /// - internal static class FloatExtensions - { - /// - /// Returns a representation of a that avoids scientific notation, which is not compatible with the composition expression animations API - /// - /// The input to process - /// A representation of that can be used in a expression animation - [Pure] - public static string ToCompositionString(this float number) - { - var defaultString = number.ToString(System.Globalization.CultureInfo.InvariantCulture); - var eIndex = defaultString.IndexOf('E'); - - // If the default string representation is not in scientific notation, we can use it - if (eIndex == -1) - { - return defaultString; - } - - // If the number uses scientific notation because it is too large, we can print it without the decimal places - var exponent = int.Parse(defaultString.Substring(eIndex + 1)); - if (exponent >= 0) - { - return number.ToString($"F0", System.Globalization.CultureInfo.InvariantCulture); - } - - // Otherwise, we need to print it with the right number of decimals - var decimalPlaces = -exponent // The number of decimal places is the exponent of 10 - + eIndex // Plus each character in the mantissa - + (number < 0 ? - -3 : // Minus the sign, dot and first number of the mantissa if negative - -2); // Minus the dot and first number of the mantissa otherwise - - return number.ToString($"F{decimalPlaces}", System.Globalization.CultureInfo.InvariantCulture); - } - } -} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/OperationType.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/OperationType.cs deleted file mode 100644 index 6728b93dc..000000000 --- a/labs/CompositionCollectionView/ExpressionsFork/Expressions/OperationType.cs +++ /dev/null @@ -1,47 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork -{ - /// - /// Enum OperationType - /// - internal enum OperationType - { - /// - /// The function - /// - Function, - - /// - /// The operator (takes two operands) - /// - Operator, - - /// - /// The operator that only takes one operand - /// - UnaryOperator, - - /// - /// The constant - /// - Constant, - - /// - /// The reference - /// - Reference, - - /// - /// The conditional - /// - Conditional, - - /// - /// The swizzle - /// - Swizzle, - } -} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/AmbientLightReferenceNode.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/AmbientLightReferenceNode.cs deleted file mode 100644 index edce187bd..000000000 --- a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/AmbientLightReferenceNode.cs +++ /dev/null @@ -1,46 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Windows.UI.Composition; - -namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork -{ - /// - /// Class AmbientLightReferenceNode. This class cannot be inherited. - /// - /// - public sealed class AmbientLightReferenceNode : ReferenceNode - { - /// - /// Initializes a new instance of the class. - /// - /// Name of the parameter. - /// The light. - internal AmbientLightReferenceNode(string paramName, AmbientLight light = null) - : base(paramName, light) - { - } - - /// - /// Creates the target reference. - /// - /// AmbientLightReferenceNode. - internal static AmbientLightReferenceNode CreateTargetReference() - { - var node = new AmbientLightReferenceNode(null); - node.NodeType = ExpressionNodeType.TargetReference; - - return node; - } - - /// - /// Gets the color. - /// - /// The color. - public ColorNode Color - { - get { return ReferenceProperty("Color"); } - } - } -} diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/ColorBrushReferenceNode.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/ColorBrushReferenceNode.cs deleted file mode 100644 index 0a20a4e94..000000000 --- a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/ColorBrushReferenceNode.cs +++ /dev/null @@ -1,46 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Windows.UI.Composition; - -namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork -{ - /// - /// Class ColorBrushReferenceNode. This class cannot be inherited. - /// - /// - public sealed class ColorBrushReferenceNode : ReferenceNode - { - /// - /// Initializes a new instance of the class. - /// - /// Name of the parameter. - /// The brush. - internal ColorBrushReferenceNode(string paramName, CompositionColorBrush brush = null) - : base(paramName, brush) - { - } - - /// - /// Creates the target reference. - /// - /// ColorBrushReferenceNode. - internal static ColorBrushReferenceNode CreateTargetReference() - { - var node = new ColorBrushReferenceNode(null); - node.NodeType = ExpressionNodeType.TargetReference; - - return node; - } - - /// - /// Gets the color. - /// - /// The color. - public ColorNode Color - { - get { return ReferenceProperty("Color"); } - } - } -} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/DistantLightReferenceNode.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/DistantLightReferenceNode.cs deleted file mode 100644 index 2aa369217..000000000 --- a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/DistantLightReferenceNode.cs +++ /dev/null @@ -1,55 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Windows.UI.Composition; - -namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork -{ - /// - /// Class DistantLightReferenceNode. This class cannot be inherited. - /// - /// - public sealed class DistantLightReferenceNode : ReferenceNode - { - /// - /// Initializes a new instance of the class. - /// - /// Name of the parameter. - /// The light. - internal DistantLightReferenceNode(string paramName, DistantLight light = null) - : base(paramName, light) - { - } - - /// - /// Creates the target reference. - /// - /// DistantLightReferenceNode. - internal static DistantLightReferenceNode CreateTargetReference() - { - var node = new DistantLightReferenceNode(null); - node.NodeType = ExpressionNodeType.TargetReference; - - return node; - } - - /// - /// Gets the color. - /// - /// The color. - public ColorNode Color - { - get { return ReferenceProperty("Color"); } - } - - /// - /// Gets the direction. - /// - /// The direction. - public Vector3Node Direction - { - get { return ReferenceProperty("Direction"); } - } - } -} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/DropShadowReferenceNode.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/DropShadowReferenceNode.cs deleted file mode 100644 index 658642177..000000000 --- a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/DropShadowReferenceNode.cs +++ /dev/null @@ -1,73 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Windows.UI.Composition; - -namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork -{ - /// - /// Class DropShadowReferenceNode. This class cannot be inherited. - /// - /// - public sealed class DropShadowReferenceNode : ReferenceNode - { - /// - /// Initializes a new instance of the class. - /// - /// Name of the parameter. - /// The source. - internal DropShadowReferenceNode(string paramName, DropShadow source = null) - : base(paramName, source) - { - } - - /// - /// Creates the target reference. - /// - /// DropShadowReferenceNode. - internal static DropShadowReferenceNode CreateTargetReference() - { - var node = new DropShadowReferenceNode(null); - node.NodeType = ExpressionNodeType.TargetReference; - - return node; - } - - /// - /// Gets the blur radius. - /// - /// The blur radius. - public ScalarNode BlurRadius - { - get { return ReferenceProperty("BlurRadius"); } - } - - /// - /// Gets the opacity. - /// - /// The opacity. - public ScalarNode Opacity - { - get { return ReferenceProperty("Opacity"); } - } - - /// - /// Gets the offset. - /// - /// The offset. - public Vector3Node Offset - { - get { return ReferenceProperty("Offset"); } - } - - /// - /// Gets the color. - /// - /// The color. - public ColorNode Color - { - get { return ReferenceProperty("Color"); } - } - } -} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/InsetClipReferenceNode.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/InsetClipReferenceNode.cs deleted file mode 100644 index f83f28944..000000000 --- a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/InsetClipReferenceNode.cs +++ /dev/null @@ -1,136 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Windows.UI.Composition; - -namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork -{ - /// - /// Class InsetClipReferenceNode. This class cannot be inherited. - /// - /// - public sealed class InsetClipReferenceNode : ReferenceNode - { - /// - /// Initializes a new instance of the class. - /// - /// Name of the parameter. - /// The ic. - internal InsetClipReferenceNode(string paramName, InsetClip ic = null) - : base(paramName, ic) - { - } - - /// - /// Creates the target reference. - /// - /// InsetClipReferenceNode. - internal static InsetClipReferenceNode CreateTargetReference() - { - var node = new InsetClipReferenceNode(null); - node.NodeType = ExpressionNodeType.TargetReference; - - return node; - } - - /// - /// Gets the bottom inset. - /// - /// The bottom inset. - public ScalarNode BottomInset - { - get { return ReferenceProperty("BottomInset"); } - } - - /// - /// Gets the left inset. - /// - /// The left inset. - public ScalarNode LeftInset - { - get { return ReferenceProperty("LeftInset"); } - } - - /// - /// Gets the right inset. - /// - /// The right inset. - public ScalarNode RightInset - { - get { return ReferenceProperty("RightInset"); } - } - - /// - /// Gets the top inset. - /// - /// The top inset. - public ScalarNode TopInset - { - get { return ReferenceProperty("TopInset"); } - } - - /// - /// Gets the rotation angle. - /// - /// The rotation angle. - public ScalarNode RotationAngle - { - get { return ReferenceProperty("RotationAngle"); } - } - - /// - /// Gets the rotation angle in degrees. - /// - /// The rotation angle in degrees. - public ScalarNode RotationAngleInDegrees - { - get { return ReferenceProperty("RotationAngleInDegrees"); } - } - - /// - /// Gets the anchor point. - /// - /// The anchor point. - public Vector2Node AnchorPoint - { - get { return ReferenceProperty("AnchorPoint"); } - } - - /// - /// Gets the center point. - /// - /// The center point. - public Vector2Node CenterPoint - { - get { return ReferenceProperty("CenterPoint"); } - } - - /// - /// Gets the offset. - /// - /// The offset. - public Vector2Node Offset - { - get { return ReferenceProperty("Offset"); } - } - - /// - /// Gets the scale. - /// - /// The scale. - public Vector2Node Scale - { - get { return ReferenceProperty("Scale"); } - } - - /// - /// Gets the transform matrix. - /// - /// The transform matrix. - public Matrix3x2Node TransformMatrix - { - get { return ReferenceProperty("TransformMatrix"); } - } - } -} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/InteractionTrackerReferenceNode.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/InteractionTrackerReferenceNode.cs deleted file mode 100644 index e730515d1..000000000 --- a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/InteractionTrackerReferenceNode.cs +++ /dev/null @@ -1,154 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Windows.UI.Composition.Interactions; - -namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork -{ - /// - /// Class InteractionTrackerReferenceNode. This class cannot be inherited. - /// - /// - public sealed class InteractionTrackerReferenceNode : ReferenceNode - { - /// - /// Initializes a new instance of the class. - /// - /// Name of the parameter. - /// It. - internal InteractionTrackerReferenceNode(string paramName, InteractionTracker it = null) - : base(paramName, it) - { - } - - /// - /// Creates the target reference. - /// - /// InteractionTrackerReferenceNode. - internal static InteractionTrackerReferenceNode CreateTargetReference() - { - var node = new InteractionTrackerReferenceNode(null); - node.NodeType = ExpressionNodeType.TargetReference; - - return node; - } - - /// - /// Gets the is position rounding suggested. - /// - /// The is position rounding suggested. - public BooleanNode IsPositionRoundingSuggested - { - get { return ReferenceProperty("IsPositionRoundingSuggested"); } - } - - /// - /// Gets the minimum scale. - /// - /// The minimum scale. - public ScalarNode MinScale - { - get { return ReferenceProperty("MinScale"); } - } - - /// - /// Gets the maximum scale. - /// - /// The maximum scale. - public ScalarNode MaxScale - { - get { return ReferenceProperty("MaxScale"); } - } - - /// - /// Gets the natural resting scale. - /// - /// The natural resting scale. - public ScalarNode NaturalRestingScale - { - get { return ReferenceProperty("NaturalRestingScale"); } - } - - /// - /// Gets the scale. - /// - /// The scale. - public ScalarNode Scale - { - get { return ReferenceProperty("Scale"); } - } - - /// - /// Gets the scale inertia decay rate. - /// - /// The scale inertia decay rate. - public ScalarNode ScaleInertiaDecayRate - { - get { return ReferenceProperty("ScaleInertiaDecayRate"); } - } - - /// - /// Gets the scale velocity in percent per second. - /// - /// The scale velocity in percent per second. - public ScalarNode ScaleVelocityInPercentPerSecond - { - get { return ReferenceProperty("ScaleVelocityInPercentPerSecond"); } - } - - /// - /// Gets the minimum position. - /// - /// The minimum position. - public Vector3Node MinPosition - { - get { return ReferenceProperty("MinPosition"); } - } - - /// - /// Gets the maximum position. - /// - /// The maximum position. - public Vector3Node MaxPosition - { - get { return ReferenceProperty("MaxPosition"); } - } - - /// - /// Gets the natural resting position. - /// - /// The natural resting position. - public Vector3Node NaturalRestingPosition - { - get { return ReferenceProperty("NaturalRestingPosition"); } - } - - /// - /// Gets the position. - /// - /// The position. - public Vector3Node Position - { - get { return ReferenceProperty("Position"); } - } - - /// - /// Gets the position inertia decay rate. - /// - /// The position inertia decay rate. - public Vector3Node PositionInertiaDecayRate - { - get { return ReferenceProperty("PositionInertiaDecayRate"); } - } - - /// - /// Gets the position velocity in pixels per second. - /// - /// The position velocity in pixels per second. - public Vector3Node PositionVelocityInPixelsPerSecond - { - get { return ReferenceProperty("PositionVelocityInPixelsPerSecond"); } - } - } -} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/ManipulationPropertySetReferenceNode.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/ManipulationPropertySetReferenceNode.cs deleted file mode 100644 index ad71b3051..000000000 --- a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/ManipulationPropertySetReferenceNode.cs +++ /dev/null @@ -1,79 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Windows.UI.Composition; - -namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork -{ - /// - /// Class ManipulationPropertySetReferenceNode. This class cannot be inherited. - /// - /// - public sealed class ManipulationPropertySetReferenceNode : PropertySetReferenceNode - { - /// - /// Initializes a new instance of the class. - /// - /// Name of the parameter. - /// The ps. - internal ManipulationPropertySetReferenceNode(string paramName, CompositionPropertySet ps = null) - : base(paramName, ps) - { - } - - /// - /// Initializes a new instance of the class. - /// Needed for GetSpecializedReference - /// - internal ManipulationPropertySetReferenceNode() - : base(null, null) - { - } - - /// - /// Gets the center point. - /// - /// The center point. - public Vector3Node CenterPoint - { - get { return ReferenceProperty("CenterPoint"); } - } - - /// - /// Gets the pan. - /// - /// The pan. - public Vector3Node Pan - { - get { return ReferenceProperty("Pan"); } - } - - /// - /// Gets the scale. - /// - /// The scale. - public Vector3Node Scale - { - get { return ReferenceProperty("Scale"); } - } - - /// - /// Gets the translation. - /// - /// The translation. - public Vector3Node Translation - { - get { return ReferenceProperty("Translation"); } - } - - /// - /// Gets the matrix. - /// - /// The matrix. - public Matrix4x4Node Matrix - { - get { return ReferenceProperty("Matrix"); } - } - } -} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/NineGridBrushReferenceNode.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/NineGridBrushReferenceNode.cs deleted file mode 100644 index ef9575db6..000000000 --- a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/NineGridBrushReferenceNode.cs +++ /dev/null @@ -1,109 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Windows.UI.Composition; - -namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork -{ - /// - /// Class NineGridBrushReferenceNode. This class cannot be inherited. - /// - /// - public sealed class NineGridBrushReferenceNode : ReferenceNode - { - /// - /// Initializes a new instance of the class. - /// - /// Name of the parameter. - /// The brush. - internal NineGridBrushReferenceNode(string paramName, CompositionNineGridBrush brush = null) - : base(paramName, brush) - { - } - - /// - /// Creates the target reference. - /// - /// NineGridBrushReferenceNode. - internal static NineGridBrushReferenceNode CreateTargetReference() - { - var node = new NineGridBrushReferenceNode(null); - node.NodeType = ExpressionNodeType.TargetReference; - - return node; - } - - /// - /// Gets the bottom inset. - /// - /// The bottom inset. - public ScalarNode BottomInset - { - get { return ReferenceProperty("BottomInset"); } - } - - /// - /// Gets the bottom inset scale. - /// - /// The bottom inset scale. - public ScalarNode BottomInsetScale - { - get { return ReferenceProperty("BottomInsetScale"); } - } - - /// - /// Gets the left inset. - /// - /// The left inset. - public ScalarNode LeftInset - { - get { return ReferenceProperty("LeftInset"); } - } - - /// - /// Gets the left inset scale. - /// - /// The left inset scale. - public ScalarNode LeftInsetScale - { - get { return ReferenceProperty("LeftInsetScale"); } - } - - /// - /// Gets the right inset. - /// - /// The right inset. - public ScalarNode RightInset - { - get { return ReferenceProperty("RightInset"); } - } - - /// - /// Gets the right inset scale. - /// - /// The right inset scale. - public ScalarNode RightInsetScale - { - get { return ReferenceProperty("RightInsetScale"); } - } - - /// - /// Gets the top inset. - /// - /// The top inset. - public ScalarNode TopInset - { - get { return ReferenceProperty("TopInset"); } - } - - /// - /// Gets the top inset scale. - /// - /// The top inset scale. - public ScalarNode TopInsetScale - { - get { return ReferenceProperty("TopInsetScale"); } - } - } -} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/PointLightReferenceNode.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/PointLightReferenceNode.cs deleted file mode 100644 index e64d570da..000000000 --- a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/PointLightReferenceNode.cs +++ /dev/null @@ -1,91 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Windows.UI.Composition; - -namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork -{ - /// - /// Class PointLightReferenceNode. This class cannot be inherited. - /// - /// - public sealed class PointLightReferenceNode : ReferenceNode - { - /// - /// Initializes a new instance of the class. - /// - /// Name of the parameter. - /// The light. - internal PointLightReferenceNode(string paramName, PointLight light = null) - : base(paramName, light) - { - } - - /// - /// Creates the target reference. - /// - /// PointLightReferenceNode. - internal static PointLightReferenceNode CreateTargetReference() - { - var node = new PointLightReferenceNode(null); - node.NodeType = ExpressionNodeType.TargetReference; - - return node; - } - - /// - /// Gets the constant attenuation. - /// - /// The constant attenuation. - public ScalarNode ConstantAttenuation - { - get { return ReferenceProperty("ConstantAttenuation"); } - } - - /// - /// Gets the linear attenuation. - /// - /// The linear attenuation. - public ScalarNode LinearAttenuation - { - get { return ReferenceProperty("LinearAttenuation"); } - } - - /// - /// Gets the quadratic attenuation. - /// - /// The quadratic attenuation. - public ScalarNode QuadraticAttentuation - { - get { return ReferenceProperty("QuadraticAttentuation"); } - } - - /// - /// Gets the color. - /// - /// The color. - public ColorNode Color - { - get { return ReferenceProperty("Color"); } - } - - /// - /// Gets the direction. - /// - /// The direction. - public Vector3Node Direction - { - get { return ReferenceProperty("Direction"); } - } - - /// - /// Gets the offset. - /// - /// The offset. - public Vector3Node Offset - { - get { return ReferenceProperty("Offset"); } - } - } -} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/PointerPositionPropertySetReferenceNode.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/PointerPositionPropertySetReferenceNode.cs deleted file mode 100644 index 968db6d1e..000000000 --- a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/PointerPositionPropertySetReferenceNode.cs +++ /dev/null @@ -1,43 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Windows.UI.Composition; - -namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork -{ - /// - /// Class PointerPositionPropertySetReferenceNode. This class cannot be inherited. - /// - /// - public sealed class PointerPositionPropertySetReferenceNode : PropertySetReferenceNode - { - /// - /// Initializes a new instance of the class. - /// - /// Name of the parameter. - /// The ps. - internal PointerPositionPropertySetReferenceNode(string paramName, CompositionPropertySet ps = null) - : base(paramName, ps) - { - } - - /// - /// Initializes a new instance of the class. - /// Needed for GetSpecializedReference - /// - internal PointerPositionPropertySetReferenceNode() - : base(null, null) - { - } - - /// - /// Gets the position. - /// - /// The position. - public Vector3Node Position - { - get { return ReferenceProperty("Position"); } - } - } -} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/PropertySetReferenceNode.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/PropertySetReferenceNode.cs deleted file mode 100644 index b0f9d132b..000000000 --- a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/PropertySetReferenceNode.cs +++ /dev/null @@ -1,52 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Windows.UI.Composition; - -namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork -{ - /// - /// Class PropertySetReferenceNode. - /// - /// - public class PropertySetReferenceNode : ReferenceNode - { - /// - /// Initializes a new instance of the class. - /// - /// Name of the parameter. - /// The ps. - internal PropertySetReferenceNode(string paramName, CompositionPropertySet ps = null) - : base(paramName, ps) - { - } - - /// - /// Initializes a new instance of the class. - /// - // Needed for GetSpecializedReference<>() - internal PropertySetReferenceNode() - : base(null, null) - { - } - - /// - /// Gets or sets the source. - /// - /// The source. - internal CompositionPropertySet Source { get; set; } - - /// - /// Creates the target reference. - /// - /// PropertySetReferenceNode. - internal static PropertySetReferenceNode CreateTargetReference() - { - var node = new PropertySetReferenceNode(null); - node.NodeType = ExpressionNodeType.TargetReference; - - return node; - } - } -} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/ReferenceNode.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/ReferenceNode.cs deleted file mode 100644 index aeb180862..000000000 --- a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/ReferenceNode.cs +++ /dev/null @@ -1,168 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using Windows.UI.Composition; - -namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork -{ - /// - /// Class ReferenceNode. - /// - /// - public abstract class ReferenceNode : ExpressionNode - { - /// - /// Initializes a new instance of the class. - /// - /// Name of the parameter. - /// The comp object. - internal ReferenceNode(string paramName, CompositionObject compObj = null) - { - Reference = compObj; - NodeType = ExpressionNodeType.Reference; - ParamName = paramName; - } - - /// - /// Gets the reference. - /// - /// The reference. - public CompositionObject Reference { get; private set; } - - /// - /// Create a reference to the specified boolean property. This maybe be a property on the CompositionObject directly, or on the its PropertySet. - /// - /// The name of the property to reference. - /// BooleanNode. - public BooleanNode GetBooleanProperty(string propertyName) - { - return ReferenceProperty(propertyName); - } - - /// - /// Create a reference to the specified float property. This maybe be a property on the CompositionObject directly, or on the its PropertySet. - /// - /// The name of the property to reference. - /// ScalarNode - public ScalarNode GetScalarProperty(string propertyName) - { - return ReferenceProperty(propertyName); - } - - /// - /// Create a reference to the specified Vector2 property. This maybe be a property on the CompositionObject directly, or on the its PropertySet. - /// - /// The name of the property to reference. - /// Vector2Node - public Vector2Node GetVector2Property(string propertyName) - { - return ReferenceProperty(propertyName); - } - - /// - /// Create a reference to the specified Vector3 property. This maybe be a property on the CompositionObject directly, or on the its PropertySet. - /// - /// The name of the property to reference. - /// Vector3Node - public Vector3Node GetVector3Property(string propertyName) - { - return ReferenceProperty(propertyName); - } - - /// - /// Create a reference to the specified Vector4 property. This maybe be a property on the CompositionObject directly, or on the its PropertySet. - /// - /// The name of the property to reference. - /// Vector4Node - public Vector4Node GetVector4Property(string propertyName) - { - return ReferenceProperty(propertyName); - } - - /// - /// Create a reference to the specified Color property. This maybe be a property on the CompositionObject directly, or on the its PropertySet. - /// - /// The name of the property to reference. - /// ColorNode - public ColorNode GetColorProperty(string propertyName) - { - return ReferenceProperty(propertyName); - } - - /// - /// Create a reference to the specified Quaternion property. This maybe be a property on the CompositionObject directly, or on the its PropertySet. - /// - /// The name of the property to reference. - /// QuaternionNode - public QuaternionNode GetQuaternionProperty(string propertyName) - { - return ReferenceProperty(propertyName); - } - - /// - /// Create a reference to the specified Matrix3x2 property. This maybe be a property on the CompositionObject directly, or on the its PropertySet. - /// - /// The name of the property to reference. - /// Matrix3x2Node - public Matrix3x2Node GetMatrix3x2Property(string propertyName) - { - return ReferenceProperty(propertyName); - } - - /// - /// Create a reference to the specified Matrix4x4 property. This maybe be a property on the CompositionObject directly, or on the its PropertySet. - /// - /// The name of the property to reference. - /// Matrix4x4Node - public Matrix4x4Node GetMatrix4x4Property(string propertyName) - { - return ReferenceProperty(propertyName); - } - - /// - /// Gets the reference parameter string. - /// - /// System.String. - internal string GetReferenceParamString() - { - if (NodeType == ExpressionNodeType.TargetReference) - { - return "this.target"; - } - else - { - return ParamName; - } - } - - /// - /// References the property. - /// - /// A class that derives from ExpressionNode. - /// Name of the property. - /// T. - protected internal T ReferenceProperty(string propertyName) - where T : ExpressionNode - { - T newNode = ExpressionNode.CreateExpressionNode(); - - (newNode as ExpressionNode).NodeType = ExpressionNodeType.ReferenceProperty; - (newNode as ExpressionNode).Children.Add(this); - (newNode as ExpressionNode).PropertyName = propertyName; - - return newNode; - } - - /// - /// Gets the value. - /// - /// System.String. - /// GetValue is not implemented for ReferenceNode and shouldn't be called - protected internal override string GetValue() - { - throw new NotImplementedException("GetValue is not implemented for ReferenceNode and shouldn't be called"); - } - } -} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/SpotLightReferenceNode.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/SpotLightReferenceNode.cs deleted file mode 100644 index b0530064d..000000000 --- a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/SpotLightReferenceNode.cs +++ /dev/null @@ -1,145 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Windows.UI.Composition; - -namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork -{ - /// - /// Class SpotLightReferenceNode. This class cannot be inherited. - /// - /// - public sealed class SpotLightReferenceNode : ReferenceNode - { - /// - /// Initializes a new instance of the class. - /// - /// Name of the parameter. - /// The light. - internal SpotLightReferenceNode(string paramName, SpotLight light = null) - : base(paramName, light) - { - } - - /// - /// Creates the target reference. - /// - /// SpotLightReferenceNode. - internal static SpotLightReferenceNode CreateTargetReference() - { - var node = new SpotLightReferenceNode(null); - node.NodeType = ExpressionNodeType.TargetReference; - - return node; - } - - /// - /// Gets the constant attenuation. - /// - /// The constant attenuation. - public ScalarNode ConstantAttenuation - { - get { return ReferenceProperty("ConstantAttenuation"); } - } - - /// - /// Gets the linear attenuation. - /// - /// The linear attenuation. - public ScalarNode LinearAttenuation - { - get { return ReferenceProperty("LinearAttenuation"); } - } - - /// - /// Gets the quadratic attenuation. - /// - /// The quadratic attenuation. - public ScalarNode QuadraticAttentuation - { - get { return ReferenceProperty("QuadraticAttentuation"); } - } - - /// - /// Gets the inner cone angle. - /// - /// The inner cone angle. - public ScalarNode InnerConeAngle - { - get { return ReferenceProperty("InnerConeAngle"); } - } - - /// - /// Gets the inner cone angle in degrees. - /// - /// The inner cone angle in degrees. - public ScalarNode InnerConeAngleInDegrees - { - get { return ReferenceProperty("InnerConeAngleInDegrees"); } - } - - /// - /// Gets the outer cone angle. - /// - /// The outer cone angle. - public ScalarNode OuterConeAngle - { - get { return ReferenceProperty("OuterConeAngle"); } - } - - /// - /// Gets the outer cone angle in degrees. - /// - /// The outer cone angle in degrees. - public ScalarNode OuterConeAngleInDegrees - { - get { return ReferenceProperty("OuterConeAngleInDegrees"); } - } - - /// - /// Gets the color. - /// - /// The color. - public ColorNode Color - { - get { return ReferenceProperty("Color"); } - } - - /// - /// Gets the color of the inner cone. - /// - /// The color of the inner cone. - public ColorNode InnerConeColor - { - get { return ReferenceProperty("InnerConeColor"); } - } - - /// - /// Gets the color of the outer cone. - /// - /// The color of the outer cone. - public ColorNode OuterConeColor - { - get { return ReferenceProperty("OuterConeColor"); } - } - - /// - /// Gets the direction. - /// - /// The direction. - public Vector3Node Direction - { - get { return ReferenceProperty("Direction"); } - } - - /// - /// Gets the offset. - /// - /// The offset. - public Vector3Node Offset - { - get { return ReferenceProperty("Offset"); } - } - } -} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/SurfaceBrushReferenceNode.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/SurfaceBrushReferenceNode.cs deleted file mode 100644 index a5b35cdae..000000000 --- a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/SurfaceBrushReferenceNode.cs +++ /dev/null @@ -1,154 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Windows.UI.Composition; - -namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork -{ - /// - /// Class SurfaceBrushReferenceNode. This class cannot be inherited. - /// - /// - public sealed class SurfaceBrushReferenceNode : ReferenceNode - { - /// - /// Initializes a new instance of the class. - /// - /// Name of the parameter. - /// The brush. - internal SurfaceBrushReferenceNode(string paramName, CompositionSurfaceBrush brush = null) - : base(paramName, brush) - { - } - - /// - /// Creates the target reference. - /// - /// SurfaceBrushReferenceNode. - internal static SurfaceBrushReferenceNode CreateTargetReference() - { - var node = new SurfaceBrushReferenceNode(null); - node.NodeType = ExpressionNodeType.TargetReference; - - return node; - } - - /// - /// Gets the horizontal alignment ratio. - /// - /// The horizontal alignment ratio. - public ScalarNode HorizontalAlignmentRatio - { - get { return ReferenceProperty("HorizontalAlignmentRatio"); } - } - - /// - /// Gets the vertical alignment ratio. - /// - /// The vertical alignment ratio. - public ScalarNode VerticalAlignmentRatio - { - get { return ReferenceProperty("VerticalAlignmentRatio"); } - } - - /// - /// Gets the bottom inset. - /// - /// The bottom inset. - public ScalarNode BottomInset - { - get { return ReferenceProperty("BottomInset"); } - } - - /// - /// Gets the left inset. - /// - /// The left inset. - public ScalarNode LeftInset - { - get { return ReferenceProperty("LeftInset"); } - } - - /// - /// Gets the right inset. - /// - /// The right inset. - public ScalarNode RightInset - { - get { return ReferenceProperty("RightInset"); } - } - - /// - /// Gets the top inset. - /// - /// The top inset. - public ScalarNode TopInset - { - get { return ReferenceProperty("TopInset"); } - } - - /// - /// Gets the rotation angle. - /// - /// The rotation angle. - public ScalarNode RotationAngle - { - get { return ReferenceProperty("RotationAngle"); } - } - - /// - /// Gets the rotation angle in degrees. - /// - /// The rotation angle in degrees. - public ScalarNode RotationAngleInDegrees - { - get { return ReferenceProperty("RotationAngleInDegrees"); } - } - - /// - /// Gets the anchor point. - /// - /// The anchor point. - public Vector2Node AnchorPoint - { - get { return ReferenceProperty("AnchorPoint"); } - } - - /// - /// Gets the center point. - /// - /// The center point. - public Vector2Node CenterPoint - { - get { return ReferenceProperty("CenterPoint"); } - } - - /// - /// Gets the offset. - /// - /// The offset. - public Vector2Node Offset - { - get { return ReferenceProperty("Offset"); } - } - - /// - /// Gets the scale. - /// - /// The scale. - public Vector2Node Scale - { - get { return ReferenceProperty("Scale"); } - } - - /// - /// Gets the transform matrix. - /// - /// The transform matrix. - public Matrix3x2Node TransformMatrix - { - get { return ReferenceProperty("TransformMatrix"); } - } - } -} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/VisualReferenceNode.cs b/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/VisualReferenceNode.cs deleted file mode 100644 index f324aed88..000000000 --- a/labs/CompositionCollectionView/ExpressionsFork/Expressions/ReferenceNodes/VisualReferenceNode.cs +++ /dev/null @@ -1,162 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Windows.UI.Composition; - -namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork -{ - /// - /// Class VisualReferenceNode. This class cannot be inherited. - /// - /// - public sealed class VisualReferenceNode : ReferenceNode - { - /// - /// Initializes a new instance of the class. - /// - /// Name of the parameter. - /// The v. - internal VisualReferenceNode(string paramName, Visual v = null) - : base(paramName, v) - { - } - - /// - /// Creates the target reference. - /// - /// VisualReferenceNode. - internal static VisualReferenceNode CreateTargetReference() - { - var node = new VisualReferenceNode(null); - node.NodeType = ExpressionNodeType.TargetReference; - - return node; - } - - /// - /// Gets the opacity. - /// - /// The opacity. - public ScalarNode Opacity - { - get { return ReferenceProperty("Opacity"); } - } - - /// - /// Gets the rotation angle. - /// - /// The rotation angle. - public ScalarNode RotationAngle - { - get { return ReferenceProperty("RotationAngle"); } - } - - /// - /// Gets the rotation angle in degrees. - /// - /// The rotation angle in degrees. - public ScalarNode RotationAngleInDegrees - { - get { return ReferenceProperty("RotationAngleInDegrees"); } - } - - /// - /// Gets the anchor point. - /// - /// The anchor point. - public Vector2Node AnchorPoint - { - get { return ReferenceProperty("AnchorPoint"); } - } - - /// - /// Gets the size of the relative. - /// - /// The size of the relative. - public Vector2Node RelativeSize - { - get { return ReferenceProperty("RelativeSize"); } - } - - /// - /// Gets the size. - /// - /// The size. - public Vector2Node Size - { - get { return ReferenceProperty("Size"); } - } - - /// - /// Gets the center point. - /// - /// The center point. - public Vector3Node CenterPoint - { - get { return ReferenceProperty("CenterPoint"); } - } - - /// - /// Gets the offset. - /// - /// The offset. - public Vector3Node Offset - { - get { return ReferenceProperty("Offset"); } - } - - /// - /// Gets the relative offset. - /// - /// The relative offset. - public Vector3Node RelativeOffset - { - get { return ReferenceProperty("RelativeOffset"); } - } - - /// - /// Gets the rotation axis. - /// - /// The rotation axis. - public Vector3Node RotationAxis - { - get { return ReferenceProperty("RotationAxis"); } - } - - /// - /// Gets the scale. - /// - /// The scale. - public Vector3Node Scale - { - get { return ReferenceProperty("Scale"); } - } - - /// - /// Gets the Translation. - /// - public Vector3Node Translation - { - get { return GetVector3Property("Translation"); } - } - - /// - /// Gets the orientation. - /// - /// The orientation. - public QuaternionNode Orientation - { - get { return ReferenceProperty("Orientation"); } - } - - /// - /// Gets the transform matrix. - /// - /// The transform matrix. - public Matrix4x4Node TransformMatrix - { - get { return ReferenceProperty("TransformMatrix"); } - } - } -} \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/ExpressionsFork.csproj b/labs/CompositionCollectionView/ExpressionsFork/ExpressionsFork.csproj deleted file mode 100644 index 87e0e62b9..000000000 --- a/labs/CompositionCollectionView/ExpressionsFork/ExpressionsFork.csproj +++ /dev/null @@ -1,189 +0,0 @@ - - - - - Debug - AnyCPU - {1E97AC9F-CB43-4B98-AEF9-2BA035E037A7} - Library - Properties - ExpressionsFork - ExpressionsFork - en-US - UAP - 10.0.22000.0 - 10.0.17763.0 - 14 - 512 - {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - disable - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP - prompt - 4 - true - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE;NETFX_CORE;WINDOWS_UWP - prompt - 4 - true - - - x86 - true - bin\x86\Debug\ - DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP - ;2008 - full - false - prompt - - - x86 - bin\x86\Release\ - TRACE;NETFX_CORE;WINDOWS_UWP - true - ;2008 - pdbonly - false - prompt - true - - - - - ARM - true - bin\ARM\Debug\ - DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP - ;2008 - full - false - prompt - - - ARM - bin\ARM\Release\ - TRACE;NETFX_CORE;WINDOWS_UWP - true - ;2008 - pdbonly - false - prompt - - - ARM64 - true - bin\ARM64\Debug\ - DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP - ;2008 - full - false - prompt - - - ARM64 - bin\ARM64\Release\ - TRACE;NETFX_CORE;WINDOWS_UWP - true - ;2008 - pdbonly - false - prompt - true - - - x64 - true - bin\x64\Debug\ - DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP - ;2008 - full - false - prompt - - true - - - x64 - bin\x64\Release\ - TRACE;NETFX_CORE;WINDOWS_UWP - true - ;2008 - pdbonly - false - prompt - true - - - PackageReference - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 6.2.11 - - - - 14.0 - - - - \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/ExpressionsFork.nuspec b/labs/CompositionCollectionView/ExpressionsFork/ExpressionsFork.nuspec deleted file mode 100644 index 4bf128073..000000000 --- a/labs/CompositionCollectionView/ExpressionsFork/ExpressionsFork.nuspec +++ /dev/null @@ -1,36 +0,0 @@ - - - - CommunityToolkit.ExpressionAnimations.Fork - 0.0.4 - CommunityToolkit.ExpressionAnimations.Fork - arcadiog - false - MIT - Private fork of the ExpressionAnimations feature from the CommunityToolkit - $copyright$ - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Properties/AssemblyInfo.cs b/labs/CompositionCollectionView/ExpressionsFork/Properties/AssemblyInfo.cs deleted file mode 100644 index 6f32dca70..000000000 --- a/labs/CompositionCollectionView/ExpressionsFork/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("ExpressionsFork")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("ExpressionsFork")] -[assembly: AssemblyCopyright("Copyright © 2022")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] -[assembly: ComVisible(false)] \ No newline at end of file diff --git a/labs/CompositionCollectionView/ExpressionsFork/Properties/ExpressionsFork.rd.xml b/labs/CompositionCollectionView/ExpressionsFork/Properties/ExpressionsFork.rd.xml deleted file mode 100644 index b824333d1..000000000 --- a/labs/CompositionCollectionView/ExpressionsFork/Properties/ExpressionsFork.rd.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/BasicSample.xaml b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/BasicSample.xaml index 69873c5cf..ead3ac6fa 100644 --- a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/BasicSample.xaml +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/BasicSample.xaml @@ -1,7 +1,7 @@ - Add element - diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/BasicSample.xaml.cs b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/BasicSample.xaml.cs index 8ee6a5eec..44b65a2e6 100644 --- a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/BasicSample.xaml.cs +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/BasicSample.xaml.cs @@ -3,7 +3,7 @@ // See the LICENSE file in the project root for more information. using CommunityToolkit.Labs.Core.SourceGenerators; using CommunityToolkit.Labs.Core.SourceGenerators.Attributes; -using CommunityToolkit.Labs.WinUI.CompositionCollectionView; +using CommunityToolkit.Labs.WinUI; using Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork; using System.Xml.Linq; @@ -68,7 +68,7 @@ public BasicSample() } #if !WINAPPSDK - public class SampleLayout : Layout + public class SampleLayout : CompositionCollectionLayout { public SampleLayout(Func elementFactory, Action log) : base(elementFactory, log) { diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CanvasSample.cs b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CanvasSample.cs index 83a0907cf..e685d2331 100644 --- a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CanvasSample.cs +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CanvasSample.cs @@ -3,7 +3,7 @@ // See the LICENSE file in the project root for more information. using CommunityToolkit.Labs.Core.SourceGenerators; using CommunityToolkit.Labs.Core.SourceGenerators.Attributes; -using CommunityToolkit.Labs.WinUI.CompositionCollectionView; +using CommunityToolkit.Labs.WinUI; using Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork; using System.Numerics; using System.Xml.Linq; @@ -80,7 +80,7 @@ public CanvasSample() } #if !WINAPPSDK - public class CanvasLayout : Layout + public class CanvasLayout : CompositionCollectionLayout { public CanvasLayout(Func elementFactory, Action log) : base(elementFactory, log) { diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CanvasSample.xaml b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CanvasSample.xaml index 9ccb9f6c6..652732cc3 100644 --- a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CanvasSample.xaml +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CanvasSample.xaml @@ -1,7 +1,7 @@ - Rearrange - diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/InteractionTrackerSample.xaml b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/InteractionTrackerSample.xaml index ffdc9a64b..aec30bad3 100644 --- a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/InteractionTrackerSample.xaml +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/InteractionTrackerSample.xaml @@ -1,13 +1,13 @@ - - diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/InteractionTrackerSample.xaml.cs b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/InteractionTrackerSample.xaml.cs index cdfc1c920..e6bb46125 100644 --- a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/InteractionTrackerSample.xaml.cs +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/InteractionTrackerSample.xaml.cs @@ -3,7 +3,7 @@ // See the LICENSE file in the project root for more information. using CommunityToolkit.Labs.Core.SourceGenerators; using CommunityToolkit.Labs.Core.SourceGenerators.Attributes; -using CommunityToolkit.Labs.WinUI.CompositionCollectionView; +using CommunityToolkit.Labs.WinUI; using Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork; using System.Numerics; @@ -70,7 +70,7 @@ public InteractionTrackerSample() #endif } #if !WINAPPSDK - public class LinearLayout : Layout + public class LinearLayout : CompositionCollectionLayout { public LinearLayout(Func elementFactory, Action log) : base(elementFactory, log) { diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/MazeSample.xaml b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/MazeSample.xaml index 37feb4dbe..3a43e4501 100644 --- a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/MazeSample.xaml +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/MazeSample.xaml @@ -1,13 +1,13 @@ - - diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/MazeSample.xaml.cs b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/MazeSample.xaml.cs index 25a6dd659..c76425087 100644 --- a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/MazeSample.xaml.cs +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/MazeSample.xaml.cs @@ -3,7 +3,7 @@ // See the LICENSE file in the project root for more information. using CommunityToolkit.Labs.Core.SourceGenerators; using CommunityToolkit.Labs.Core.SourceGenerators.Attributes; -using CommunityToolkit.Labs.WinUI.CompositionCollectionView; +using CommunityToolkit.Labs.WinUI; using Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork; using System.Numerics; using System.Xml.Linq; @@ -115,14 +115,14 @@ public MazeSample() public record Tile(TileType Type, int X, int Y); #if !WINAPPSDK - public abstract class MazeLayout : Layout + public abstract class MazeLayout : CompositionCollectionLayout { protected const string PositionNode = nameof(PositionNode); protected const string ScaleNode = nameof(ScaleNode); protected const string RotationNode = nameof(RotationNode); const string CameraTransformNode = nameof(CameraTransformNode); - public MazeLayout(Layout sourceLayout) : base(sourceLayout) + public MazeLayout(CompositionCollectionLayout sourceLayout) : base(sourceLayout) { } @@ -212,7 +212,7 @@ protected override Transition GetElementTransitionEasingFunction(ElementReferenc public class SpinningMazeLayout : MazeLayout { - public SpinningMazeLayout(Layout sourceLayout) : base(sourceLayout) + public SpinningMazeLayout(CompositionCollectionLayout sourceLayout) : base(sourceLayout) { } @@ -273,7 +273,7 @@ public TraversableMazeLayout(Func elementFactory, Action { } - public TraversableMazeLayout(Layout sourceLayout) : base(sourceLayout) + public TraversableMazeLayout(CompositionCollectionLayout sourceLayout) : base(sourceLayout) { } diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/SwitchLayoutsSample.xaml b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/SwitchLayoutsSample.xaml index 9ea26a91e..dce160619 100644 --- a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/SwitchLayoutsSample.xaml +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/SwitchLayoutsSample.xaml @@ -1,7 +1,7 @@ - - diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/SwitchLayoutsSample.xaml.cs b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/SwitchLayoutsSample.xaml.cs index 73b49cca7..f33959ac0 100644 --- a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/SwitchLayoutsSample.xaml.cs +++ b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/SwitchLayoutsSample.xaml.cs @@ -3,7 +3,7 @@ // See the LICENSE file in the project root for more information. using CommunityToolkit.Labs.Core.SourceGenerators; using CommunityToolkit.Labs.Core.SourceGenerators.Attributes; -using CommunityToolkit.Labs.WinUI.CompositionCollectionView; +using CommunityToolkit.Labs.WinUI; using Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork; using System.Numerics; @@ -67,13 +67,13 @@ public SwitchLayoutsSample() } #if !WINAPPSDK - public class LinearLayout : Layout + public class LinearLayout : CompositionCollectionLayout { public LinearLayout(Func elementFactory, Action log) : base(elementFactory, log) { } - public LinearLayout(Layout sourceLayout) : base(sourceLayout) + public LinearLayout(CompositionCollectionLayout sourceLayout) : base(sourceLayout) { } @@ -89,13 +89,13 @@ protected override Transition GetElementTransitionEasingFunction(ElementReferenc Window.Current.Compositor.CreateCubicBezierEasingFunction(new Vector2(0.25f, 0.1f), new Vector2(0.25f, 1f))); } - public class StackLayout : Layout + public class StackLayout : CompositionCollectionLayout { public StackLayout(Func elementFactory, Action log) : base(elementFactory, log) { } - public StackLayout(Layout sourceLayout) : base(sourceLayout) + public StackLayout(CompositionCollectionLayout sourceLayout) : base(sourceLayout) { } diff --git a/labs/CompositionCollectionView/src/AnimatableCompositionNodeSet.cs b/labs/CompositionCollectionView/src/AnimatableNodes/AnimatableCompositionNodeSet.cs similarity index 94% rename from labs/CompositionCollectionView/src/AnimatableCompositionNodeSet.cs rename to labs/CompositionCollectionView/src/AnimatableNodes/AnimatableCompositionNodeSet.cs index 0fbd1c52c..7e96bf6da 100644 --- a/labs/CompositionCollectionView/src/AnimatableCompositionNodeSet.cs +++ b/labs/CompositionCollectionView/src/AnimatableNodes/AnimatableCompositionNodeSet.cs @@ -1,12 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if !WINAPPSDK #nullable enable using System.Numerics; -using Windows.UI.Composition; -namespace CommunityToolkit.Labs.WinUI.CompositionCollectionView; +namespace CommunityToolkit.Labs.WinUI; public class AnimatableCompositionNodeSet : IDisposable { private Dictionary _nodes = new(); @@ -144,4 +142,3 @@ public void Dispose() GC.SuppressFinalize(this); } } -#endif diff --git a/labs/CompositionCollectionView/src/AnimatableMatrix4x4CompositionNode.cs b/labs/CompositionCollectionView/src/AnimatableNodes/AnimatableMatrix4x4CompositionNode.cs similarity index 87% rename from labs/CompositionCollectionView/src/AnimatableMatrix4x4CompositionNode.cs rename to labs/CompositionCollectionView/src/AnimatableNodes/AnimatableMatrix4x4CompositionNode.cs index 72b4d0e1a..e9a209809 100644 --- a/labs/CompositionCollectionView/src/AnimatableMatrix4x4CompositionNode.cs +++ b/labs/CompositionCollectionView/src/AnimatableNodes/AnimatableMatrix4x4CompositionNode.cs @@ -3,13 +3,11 @@ // See the LICENSE file in the project root for more information. #nullable enable -#if !WINAPPSDK using System; using System.Numerics; -using Windows.UI.Composition; -using static CommunityToolkit.Labs.WinUI.CompositionCollectionView.AnimationConstants; +using static CommunityToolkit.Labs.WinUI.AnimationConstants; -namespace CommunityToolkit.Labs.WinUI.CompositionCollectionView; +namespace CommunityToolkit.Labs.WinUI; public class AnimatableMatrix4x4CompositionNode : IDisposable { private Visual _underlyingVisual; @@ -65,4 +63,3 @@ public void Dispose() GC.SuppressFinalize(this); } } -#endif diff --git a/labs/CompositionCollectionView/src/AnimatableQuaternionCompositionNode.cs b/labs/CompositionCollectionView/src/AnimatableNodes/AnimatableQuaternionCompositionNode.cs similarity index 87% rename from labs/CompositionCollectionView/src/AnimatableQuaternionCompositionNode.cs rename to labs/CompositionCollectionView/src/AnimatableNodes/AnimatableQuaternionCompositionNode.cs index d3b7d70bc..3875648b1 100644 --- a/labs/CompositionCollectionView/src/AnimatableQuaternionCompositionNode.cs +++ b/labs/CompositionCollectionView/src/AnimatableNodes/AnimatableQuaternionCompositionNode.cs @@ -3,13 +3,11 @@ // See the LICENSE file in the project root for more information. #nullable enable -#if !WINAPPSDK using System; using System.Numerics; -using Windows.UI.Composition; -using static CommunityToolkit.Labs.WinUI.CompositionCollectionView.AnimationConstants; +using static CommunityToolkit.Labs.WinUI.AnimationConstants; -namespace CommunityToolkit.Labs.WinUI.CompositionCollectionView; +namespace CommunityToolkit.Labs.WinUI; public class AnimatableQuaternionCompositionNode : IDisposable { private Visual _underlyingVisual; @@ -65,4 +63,3 @@ public void Dispose() GC.SuppressFinalize(this); } } -#endif diff --git a/labs/CompositionCollectionView/src/AnimatableScalarCompositionNode.cs b/labs/CompositionCollectionView/src/AnimatableNodes/AnimatableScalarCompositionNode.cs similarity index 87% rename from labs/CompositionCollectionView/src/AnimatableScalarCompositionNode.cs rename to labs/CompositionCollectionView/src/AnimatableNodes/AnimatableScalarCompositionNode.cs index ae72ff0b7..9009adeb6 100644 --- a/labs/CompositionCollectionView/src/AnimatableScalarCompositionNode.cs +++ b/labs/CompositionCollectionView/src/AnimatableNodes/AnimatableScalarCompositionNode.cs @@ -3,13 +3,11 @@ // See the LICENSE file in the project root for more information. #nullable enable -#if !WINAPPSDK using System.Numerics; -using Windows.UI.Composition; -using static CommunityToolkit.Labs.WinUI.CompositionCollectionView.AnimationConstants; +using static CommunityToolkit.Labs.WinUI.AnimationConstants; -namespace CommunityToolkit.Labs.WinUI.CompositionCollectionView; +namespace CommunityToolkit.Labs.WinUI; public class AnimatableScalarCompositionNode : IDisposable { @@ -66,4 +64,3 @@ public void Dispose() GC.SuppressFinalize(this); } } -#endif diff --git a/labs/CompositionCollectionView/src/AnimatableVector3CompositionNode.cs b/labs/CompositionCollectionView/src/AnimatableNodes/AnimatableVector3CompositionNode.cs similarity index 87% rename from labs/CompositionCollectionView/src/AnimatableVector3CompositionNode.cs rename to labs/CompositionCollectionView/src/AnimatableNodes/AnimatableVector3CompositionNode.cs index cd5336e1d..e08b5a49c 100644 --- a/labs/CompositionCollectionView/src/AnimatableVector3CompositionNode.cs +++ b/labs/CompositionCollectionView/src/AnimatableNodes/AnimatableVector3CompositionNode.cs @@ -3,13 +3,11 @@ // See the LICENSE file in the project root for more information. #nullable enable -#if !WINAPPSDK using System; using System.Numerics; -using Windows.UI.Composition; -using static CommunityToolkit.Labs.WinUI.CompositionCollectionView.AnimationConstants; +using static CommunityToolkit.Labs.WinUI.AnimationConstants; -namespace CommunityToolkit.Labs.WinUI.CompositionCollectionView; +namespace CommunityToolkit.Labs.WinUI; public class AnimatableVector3CompositionNode : IDisposable { private Visual _underlyingVisual; @@ -65,4 +63,3 @@ public void Dispose() GC.SuppressFinalize(this); } } -#endif diff --git a/labs/CompositionCollectionView/src/AnimationConstants.cs b/labs/CompositionCollectionView/src/AnimationConstants.cs index 7d70273fd..35c1029e1 100644 --- a/labs/CompositionCollectionView/src/AnimationConstants.cs +++ b/labs/CompositionCollectionView/src/AnimationConstants.cs @@ -3,11 +3,8 @@ // See the LICENSE file in the project root for more information. #nullable enable -using System; -using System.Numerics; -using Windows.UI.Composition; -namespace CommunityToolkit.Labs.WinUI.CompositionCollectionView; +namespace CommunityToolkit.Labs.WinUI; public static class AnimationConstants { // Strings for all the animatable properties of a composition visual diff --git a/labs/CompositionCollectionView/src/Behaviors/ElementInteractionTrackerBehavior.cs b/labs/CompositionCollectionView/src/Behaviors/ElementInteractionTrackerBehavior.cs index 40f58c5dd..438ce517d 100644 --- a/labs/CompositionCollectionView/src/Behaviors/ElementInteractionTrackerBehavior.cs +++ b/labs/CompositionCollectionView/src/Behaviors/ElementInteractionTrackerBehavior.cs @@ -5,8 +5,8 @@ #nullable enable using System.Collections.Generic; -namespace CommunityToolkit.Labs.WinUI.CompositionCollectionView; -public class ElementInteractionTrackerBehavior : LayoutBehavior +namespace CommunityToolkit.Labs.WinUI; +public class ElementInteractionTrackerBehavior : CompositionCollectionLayoutBehavior where TId : notnull { Dictionary> _elementTrackers = new(); diff --git a/labs/CompositionCollectionView/src/Behaviors/InteractionTrackerBehavior.cs b/labs/CompositionCollectionView/src/Behaviors/InteractionTrackerBehavior.cs index 465b87fce..93421f069 100644 --- a/labs/CompositionCollectionView/src/Behaviors/InteractionTrackerBehavior.cs +++ b/labs/CompositionCollectionView/src/Behaviors/InteractionTrackerBehavior.cs @@ -13,9 +13,9 @@ using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Hosting; -namespace CommunityToolkit.Labs.WinUI.CompositionCollectionView; - public class InteractionTrackerBehavior : LayoutBehavior - { +namespace CommunityToolkit.Labs.WinUI; + public class InteractionTrackerBehavior : CompositionCollectionLayoutBehavior where TId : notnull +{ public VisualInteractionSource InteractionSource { get; init; } public InteractionTracker Tracker { get; init; } public InteractionTrackerOwner TrackerOwner { get; init; } diff --git a/labs/CompositionCollectionView/src/Behaviors/InteractionTrackerGesture/GesturePreviewControl.cs b/labs/CompositionCollectionView/src/Behaviors/InteractionTrackerGesture/GesturePreviewControl.cs index 3134f932a..ef7b5e0b7 100644 --- a/labs/CompositionCollectionView/src/Behaviors/InteractionTrackerGesture/GesturePreviewControl.cs +++ b/labs/CompositionCollectionView/src/Behaviors/InteractionTrackerGesture/GesturePreviewControl.cs @@ -10,9 +10,9 @@ using System.Threading.Tasks; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Hosting; -using Animation = CommunityToolkit.Labs.WinUI.CompositionCollectionView.AnimationConstants; +using Animation = CommunityToolkit.Labs.WinUI.AnimationConstants; -namespace CommunityToolkit.Labs.WinUI.CompositionCollectionView; +namespace CommunityToolkit.Labs.WinUI; public abstract class GesturePreviewControl : UserControl { private ScalarNode? _opacity; diff --git a/labs/CompositionCollectionView/src/Behaviors/InteractionTrackerGesture/InteractionTrackerGesture.cs b/labs/CompositionCollectionView/src/Behaviors/InteractionTrackerGesture/InteractionTrackerGesture.cs index 0737ad5e7..cf493e650 100644 --- a/labs/CompositionCollectionView/src/Behaviors/InteractionTrackerGesture/InteractionTrackerGesture.cs +++ b/labs/CompositionCollectionView/src/Behaviors/InteractionTrackerGesture/InteractionTrackerGesture.cs @@ -11,10 +11,10 @@ using Windows.UI.Composition; using Windows.UI.Composition.Interactions; using Windows.UI.Xaml.Hosting; -using static CommunityToolkit.Labs.WinUI.CompositionCollectionView.AnimationConstants; +using static CommunityToolkit.Labs.WinUI.AnimationConstants; -namespace CommunityToolkit.Labs.WinUI.CompositionCollectionView; +namespace CommunityToolkit.Labs.WinUI; public abstract class InteractionTrackerGesture { public event EventHandler? GestureCompleted; diff --git a/labs/CompositionCollectionView/src/Behaviors/LayoutBehavior.cs b/labs/CompositionCollectionView/src/Behaviors/LayoutBehavior.cs index bd4f7958b..4c2eefacf 100644 --- a/labs/CompositionCollectionView/src/Behaviors/LayoutBehavior.cs +++ b/labs/CompositionCollectionView/src/Behaviors/LayoutBehavior.cs @@ -1,18 +1,17 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if !WINAPPSDK #nullable enable using System; -namespace CommunityToolkit.Labs.WinUI.CompositionCollectionView; -public abstract class LayoutBehavior +namespace CommunityToolkit.Labs.WinUI; +public abstract class CompositionCollectionLayoutBehavior where TId : notnull { - protected Layout Layout => _layout is null ? throw new InvalidOperationException("Behavior has not been added to any layout yet") : _layout; - private Layout? _layout = null; + protected CompositionCollectionLayout Layout => _layout is null ? throw new InvalidOperationException("Behavior has not been added to any layout yet") : _layout; + private CompositionCollectionLayout? _layout = null; - public void Configure(Layout layout) + public void Configure(CompositionCollectionLayout layout) { if (_layout != layout) { @@ -28,4 +27,3 @@ virtual public void OnConfigure() { } virtual public void OnActivated() { } virtual public void OnDeactivated() { } } -#endif diff --git a/labs/CompositionCollectionView/src/BindableCompositionPropertySet.cs b/labs/CompositionCollectionView/src/BindableCompositionPropertySet.cs index 41810636d..bc28c95ee 100644 --- a/labs/CompositionCollectionView/src/BindableCompositionPropertySet.cs +++ b/labs/CompositionCollectionView/src/BindableCompositionPropertySet.cs @@ -1,17 +1,14 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if !WINAPPSDK #nullable enable using System; using System.Collections.Generic; using System.ComponentModel; using System.Numerics; using System.Text; -using Windows.UI; -using Windows.UI.Composition; -namespace CommunityToolkit.Labs.WinUI.CompositionCollectionView; +namespace CommunityToolkit.Labs.WinUI; public class BindableCompositionPropertySet : INotifyPropertyChanged, IDisposable { @@ -25,11 +22,13 @@ public BindableCompositionPropertySet(CompositionPropertySet propertySet) _propertySet = propertySet; } +#if !WINAPPSDK public void InsertColor(string propertyName, Color value) { _propertySet.InsertColor(propertyName, value); OnPropertyChanged(propertyName); } +#endif public void InsertMatrix3x2(string propertyName, Matrix3x2 value) { @@ -81,7 +80,10 @@ public void InsertBoolean(string propertyName, bool value) private void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); +#if !WINAPPSDK public CompositionGetValueStatus TryGetColor(string propertyName, out Color value) => _propertySet.TryGetColor(propertyName, out value); +#endif + public CompositionGetValueStatus TryGetMatrix3x2(string propertyName, out Matrix3x2 value) => _propertySet.TryGetMatrix3x2(propertyName, out value); public CompositionGetValueStatus TryGetMatrix4x4(string propertyName, out Matrix4x4 value) => _propertySet.TryGetMatrix4x4(propertyName, out value); public CompositionGetValueStatus TryGetQuaternion(string propertyName, out Quaternion value) => _propertySet.TryGetQuaternion(propertyName, out value); @@ -124,4 +126,3 @@ public void Dispose() } #endregion } -#endif diff --git a/labs/CompositionCollectionView/src/CommunityToolkit - Backup.Labs.WinUI.CompositionCollectionView.csproj b/labs/CompositionCollectionView/src/CommunityToolkit - Backup.Labs.WinUI.CompositionCollectionView.csproj deleted file mode 100644 index a271ce127..000000000 --- a/labs/CompositionCollectionView/src/CommunityToolkit - Backup.Labs.WinUI.CompositionCollectionView.csproj +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - CommunityToolkit.Labs.WinUI.CompositionCollectionViewRns - - - - CommunityToolkit.Labs.$(PackageIdVariant).CompositionCollectionView - - This package contains CompositionCollectionView. - - 0.0.2 - warnings - True - - - - - - - - - - - - - - %(Filename) - - - - - - - - - - - - - - - - - - - MSBuild:Compile - - - MSBuild:Compile - - - MSBuild:Compile - - - MSBuild:Compile - - - MSBuild:Compile - - - diff --git a/labs/CompositionCollectionView/src/CommunityToolkit.Labs.WinUI.CompositionCollectionView.csproj b/labs/CompositionCollectionView/src/CommunityToolkit.Labs.WinUI.CompositionCollectionView.csproj index 81b62c63e..4fdabc25a 100644 --- a/labs/CompositionCollectionView/src/CommunityToolkit.Labs.WinUI.CompositionCollectionView.csproj +++ b/labs/CompositionCollectionView/src/CommunityToolkit.Labs.WinUI.CompositionCollectionView.csproj @@ -1,4 +1,4 @@ - + @@ -41,4 +41,7 @@ MSBuild:Compile + + + diff --git a/labs/CompositionCollectionView/src/CompositionCollectionView.cs b/labs/CompositionCollectionView/src/CompositionCollectionView.cs index 8e573a54e..7874e7d57 100644 --- a/labs/CompositionCollectionView/src/CompositionCollectionView.cs +++ b/labs/CompositionCollectionView/src/CompositionCollectionView.cs @@ -1,17 +1,17 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable enable - -#if !WINAPPSDK -using System; -using System.Collections; -using System.Collections.Generic; -using Windows.UI.Composition; -using Windows.UI.Xaml.Controls; - -// The Templated Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234235 -namespace CommunityToolkit.Labs.WinUI.CompositionCollectionView; +#nullable enable + +#if !WINAPPSDK +using System; +using System.Collections; +using System.Collections.Generic; +using Windows.UI.Composition; +using Windows.UI.Xaml.Controls; + +// The Templated Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234235 +namespace CommunityToolkit.Labs.WinUI; public sealed class CompositionCollectionView : Control @@ -19,7 +19,7 @@ public sealed class CompositionCollectionView : Control private Canvas? _contentPanel; private ILayout? _layout; private Action? _pendingSourceUpdate; - public Layout? Layout() => _layout as Layout; + public CompositionCollectionLayout? Layout() where TId : notnull => _layout as CompositionCollectionLayout; public delegate void LayoutChangedHandler(CompositionCollectionView sender, ILayout newLayout); public event LayoutChangedHandler? LayoutChanged; @@ -40,15 +40,15 @@ public void SetLayout(ILayout layout) } } - public void UpdateSource(IDictionary source, Action? updateCallback = null) + public void UpdateSource(IDictionary source, Action? updateCallback = null) where TId : notnull { if (_contentPanel is not null) { - (_layout as Layout)?.UpdateSource(source, updateCallback); + (_layout as CompositionCollectionLayout)?.UpdateSource(source, updateCallback); } else { - _pendingSourceUpdate = () => (_layout as Layout)?.UpdateSource(source); + _pendingSourceUpdate = () => (_layout as CompositionCollectionLayout)?.UpdateSource(source); updateCallback?.Invoke(); } } @@ -87,14 +87,14 @@ protected override void OnApplyTemplate() //Empty WINAPPSDK implementation just to get builds working #if WINAPPSDK -using System; -using System.Collections; -using System.Collections.Generic; -using Microsoft.UI.Composition; -using Microsoft.UI.Xaml.Controls; - -// The Templated Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234235 -namespace CommunityToolkit.Labs.WinUI.CompositionCollectionView; +using System; +using System.Collections; +using System.Collections.Generic; +using Microsoft.UI.Composition; +using Microsoft.UI.Xaml.Controls; + +// The Templated Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234235 +namespace CommunityToolkit.Labs.WinUI; public sealed class CompositionCollectionView : Control @@ -124,4 +124,4 @@ private void OnLayoutReplaced(ILayout sender, ILayout newLayout) } } -#endif +#endif diff --git a/labs/CompositionCollectionView/src/DeconstructPolyfillExtensions.cs b/labs/CompositionCollectionView/src/DeconstructPolyfillExtensions.cs index b6bcdba76..161857109 100644 --- a/labs/CompositionCollectionView/src/DeconstructPolyfillExtensions.cs +++ b/labs/CompositionCollectionView/src/DeconstructPolyfillExtensions.cs @@ -6,7 +6,7 @@ using System.Collections.Generic; using System.Text; -namespace CommunityToolkit.Labs.WinUI.CompositionCollectionView; +namespace CommunityToolkit.Labs.WinUI; internal static class DeconstructPolyfillExtensions { public static void Deconstruct( diff --git a/labs/CompositionCollectionView/src/ElementReference.cs b/labs/CompositionCollectionView/src/ElementReference.cs index e1bfb41e7..47b95a1ec 100644 --- a/labs/CompositionCollectionView/src/ElementReference.cs +++ b/labs/CompositionCollectionView/src/ElementReference.cs @@ -1,20 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if !WINAPPSDK #nullable enable -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using Windows.UI.Composition; -using Windows.UI.Composition.Interactions; -using Windows.UI.Xaml; -using Windows.UI.Xaml.Controls; -using Windows.UI.Xaml.Hosting; -using Windows.UI.Xaml.Input; -namespace CommunityToolkit.Labs.WinUI.CompositionCollectionView; -public record ElementReference : IDisposable +namespace CommunityToolkit.Labs.WinUI; +public record ElementReference : IDisposable where TId : notnull { private bool disposedValue; @@ -23,10 +13,10 @@ public record ElementReference : IDisposable public Visual Visual { get; init; } public CompositionPropertySet CompositionProperties { get; init; } public AnimatableCompositionNodeSet AnimatableNodes { get; init; } - public Layout Layout { get; internal set; } + public CompositionCollectionLayout Layout { get; internal set; } public TItem Model { get; internal set; } - public ElementReference(TId id, TItem model, FrameworkElement container, Layout layout) + public ElementReference(TId id, TItem model, FrameworkElement container, CompositionCollectionLayout layout) { Id = id; Container = container; @@ -37,7 +27,7 @@ public ElementReference(TId id, TItem model, FrameworkElement container, Layout< Model = model; } - internal void ReasignTo(Layout newLayout) + internal void ReasignTo(CompositionCollectionLayout newLayout) { Layout = newLayout; } @@ -79,4 +69,3 @@ public void Dispose() GC.SuppressFinalize(this); } } -#endif diff --git a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/CompositionExtensions.cs b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/CompositionExtensions.cs index fe95b4710..9f2f6fd03 100644 --- a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/CompositionExtensions.cs +++ b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/CompositionExtensions.cs @@ -2,9 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using Windows.UI.Composition; -using Windows.UI.Composition.Interactions; - namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork { /// @@ -305,4 +302,4 @@ private static ExpressionAnimation CreateExpressionAnimationFromNode(Compositor _ => 0 }; } -} \ No newline at end of file +} diff --git a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/ColorNode.cs b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/ColorNode.cs index ee696d005..801dc097f 100644 --- a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/ColorNode.cs +++ b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/ColorNode.cs @@ -4,8 +4,6 @@ // See the LICENSE file in the project root for more information. using System; -using Windows.UI; -using Windows.UI.Composition; namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork { diff --git a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/ExpressionNode.cs b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/ExpressionNode.cs index 57b302352..ccf5a9e98 100644 --- a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/ExpressionNode.cs +++ b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/ExpressionNode.cs @@ -3,12 +3,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; -using System.Collections.Generic; using System.Numerics; -using System.Runtime.CompilerServices; -using Windows.UI; -using Windows.UI.Composition; namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork { diff --git a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/Matrix4x4Node.cs b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/Matrix4x4Node.cs index e7ecaae82..1d17f76aa 100644 --- a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/Matrix4x4Node.cs +++ b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/Matrix4x4Node.cs @@ -5,7 +5,6 @@ using System; using System.Numerics; -using Windows.UI.Composition; namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork { diff --git a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/QuaternionNode.cs b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/QuaternionNode.cs index 42962dfa0..4b8c2dc87 100644 --- a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/QuaternionNode.cs +++ b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/QuaternionNode.cs @@ -5,7 +5,6 @@ using System; using System.Numerics; -using Windows.UI.Composition; namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork { diff --git a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/ScalarNode.cs b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/ScalarNode.cs index 1156b0cbb..cc824a84d 100644 --- a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/ScalarNode.cs +++ b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/ScalarNode.cs @@ -5,7 +5,6 @@ using System; using System.Numerics; -using Windows.UI.Composition; namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork { diff --git a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/Vector2Node.cs b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/Vector2Node.cs index 07072ee8f..e1328340d 100644 --- a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/Vector2Node.cs +++ b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/Vector2Node.cs @@ -5,7 +5,6 @@ using System; using System.Numerics; -using Windows.UI.Composition; namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork { diff --git a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/Vector3Node.cs b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/Vector3Node.cs index f58d9ad73..41cf42834 100644 --- a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/Vector3Node.cs +++ b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/Vector3Node.cs @@ -5,7 +5,6 @@ using System; using System.Numerics; -using Windows.UI.Composition; namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork { diff --git a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/Vector4Node.cs b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/Vector4Node.cs index 94fe0b4dd..77e8b857e 100644 --- a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/Vector4Node.cs +++ b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/Vector4Node.cs @@ -5,7 +5,6 @@ using System; using System.Numerics; -using Windows.UI.Composition; namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork { diff --git a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/AmbientLightReferenceNode.cs b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/AmbientLightReferenceNode.cs index edce187bd..ff25e3300 100644 --- a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/AmbientLightReferenceNode.cs +++ b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/AmbientLightReferenceNode.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using Windows.UI.Composition; - namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork { /// diff --git a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/ColorBrushReferenceNode.cs b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/ColorBrushReferenceNode.cs index 0a20a4e94..d4f5b0135 100644 --- a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/ColorBrushReferenceNode.cs +++ b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/ColorBrushReferenceNode.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using Windows.UI.Composition; - namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork { /// @@ -43,4 +41,4 @@ public ColorNode Color get { return ReferenceProperty("Color"); } } } -} \ No newline at end of file +} diff --git a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/DistantLightReferenceNode.cs b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/DistantLightReferenceNode.cs index 2aa369217..779dd6147 100644 --- a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/DistantLightReferenceNode.cs +++ b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/DistantLightReferenceNode.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using Windows.UI.Composition; - namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork { /// @@ -52,4 +50,4 @@ public Vector3Node Direction get { return ReferenceProperty("Direction"); } } } -} \ No newline at end of file +} diff --git a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/DropShadowReferenceNode.cs b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/DropShadowReferenceNode.cs index 658642177..46504f617 100644 --- a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/DropShadowReferenceNode.cs +++ b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/DropShadowReferenceNode.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using Windows.UI.Composition; - namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork { /// @@ -70,4 +68,4 @@ public ColorNode Color get { return ReferenceProperty("Color"); } } } -} \ No newline at end of file +} diff --git a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/InsetClipReferenceNode.cs b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/InsetClipReferenceNode.cs index f83f28944..07b98f817 100644 --- a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/InsetClipReferenceNode.cs +++ b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/InsetClipReferenceNode.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using Windows.UI.Composition; - namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork { /// @@ -133,4 +131,4 @@ public Matrix3x2Node TransformMatrix get { return ReferenceProperty("TransformMatrix"); } } } -} \ No newline at end of file +} diff --git a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/InteractionTrackerReferenceNode.cs b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/InteractionTrackerReferenceNode.cs index e730515d1..dc28486de 100644 --- a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/InteractionTrackerReferenceNode.cs +++ b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/InteractionTrackerReferenceNode.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using Windows.UI.Composition.Interactions; - namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork { /// @@ -151,4 +149,4 @@ public Vector3Node PositionVelocityInPixelsPerSecond get { return ReferenceProperty("PositionVelocityInPixelsPerSecond"); } } } -} \ No newline at end of file +} diff --git a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/ManipulationPropertySetReferenceNode.cs b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/ManipulationPropertySetReferenceNode.cs index ad71b3051..788d0a895 100644 --- a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/ManipulationPropertySetReferenceNode.cs +++ b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/ManipulationPropertySetReferenceNode.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using Windows.UI.Composition; - namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork { /// @@ -76,4 +74,4 @@ public Matrix4x4Node Matrix get { return ReferenceProperty("Matrix"); } } } -} \ No newline at end of file +} diff --git a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/NineGridBrushReferenceNode.cs b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/NineGridBrushReferenceNode.cs index ef9575db6..38c4d408b 100644 --- a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/NineGridBrushReferenceNode.cs +++ b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/NineGridBrushReferenceNode.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using Windows.UI.Composition; - namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork { /// @@ -106,4 +104,4 @@ public ScalarNode TopInsetScale get { return ReferenceProperty("TopInsetScale"); } } } -} \ No newline at end of file +} diff --git a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/PointLightReferenceNode.cs b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/PointLightReferenceNode.cs index e64d570da..7291cf2e7 100644 --- a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/PointLightReferenceNode.cs +++ b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/PointLightReferenceNode.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using Windows.UI.Composition; - namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork { /// @@ -88,4 +86,4 @@ public Vector3Node Offset get { return ReferenceProperty("Offset"); } } } -} \ No newline at end of file +} diff --git a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/PointerPositionPropertySetReferenceNode.cs b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/PointerPositionPropertySetReferenceNode.cs index 968db6d1e..3737c742e 100644 --- a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/PointerPositionPropertySetReferenceNode.cs +++ b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/PointerPositionPropertySetReferenceNode.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using Windows.UI.Composition; - namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork { /// @@ -40,4 +38,4 @@ public Vector3Node Position get { return ReferenceProperty("Position"); } } } -} \ No newline at end of file +} diff --git a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/PropertySetReferenceNode.cs b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/PropertySetReferenceNode.cs index b0f9d132b..a54477b22 100644 --- a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/PropertySetReferenceNode.cs +++ b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/PropertySetReferenceNode.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using Windows.UI.Composition; - namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork { /// @@ -49,4 +47,4 @@ internal static PropertySetReferenceNode CreateTargetReference() return node; } } -} \ No newline at end of file +} diff --git a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/ReferenceNode.cs b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/ReferenceNode.cs index aeb180862..b8ea7f73e 100644 --- a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/ReferenceNode.cs +++ b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/ReferenceNode.cs @@ -2,9 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; -using Windows.UI.Composition; - namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork { /// @@ -165,4 +162,4 @@ protected internal override string GetValue() throw new NotImplementedException("GetValue is not implemented for ReferenceNode and shouldn't be called"); } } -} \ No newline at end of file +} diff --git a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/SpotLightReferenceNode.cs b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/SpotLightReferenceNode.cs index b0530064d..5ad7dd0af 100644 --- a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/SpotLightReferenceNode.cs +++ b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/SpotLightReferenceNode.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using Windows.UI.Composition; - namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork { /// @@ -142,4 +140,4 @@ public Vector3Node Offset get { return ReferenceProperty("Offset"); } } } -} \ No newline at end of file +} diff --git a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/SurfaceBrushReferenceNode.cs b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/SurfaceBrushReferenceNode.cs index a5b35cdae..754546d6a 100644 --- a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/SurfaceBrushReferenceNode.cs +++ b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/SurfaceBrushReferenceNode.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using Windows.UI.Composition; - namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork { /// @@ -151,4 +149,4 @@ public Matrix3x2Node TransformMatrix get { return ReferenceProperty("TransformMatrix"); } } } -} \ No newline at end of file +} diff --git a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/VisualReferenceNode.cs b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/VisualReferenceNode.cs index f324aed88..dcce61509 100644 --- a/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/VisualReferenceNode.cs +++ b/labs/CompositionCollectionView/src/ExpressionsFork/Expressions/ReferenceNodes/VisualReferenceNode.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using Windows.UI.Composition; - namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork { /// @@ -159,4 +157,4 @@ public Matrix4x4Node TransformMatrix get { return ReferenceProperty("TransformMatrix"); } } } -} \ No newline at end of file +} diff --git a/labs/CompositionCollectionView/src/GlobalUsings_Local.cs b/labs/CompositionCollectionView/src/GlobalUsings_Local.cs index 2d4b636b0..46c3e394e 100644 --- a/labs/CompositionCollectionView/src/GlobalUsings_Local.cs +++ b/labs/CompositionCollectionView/src/GlobalUsings_Local.cs @@ -2,6 +2,4 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if !WINAPPSDK global using Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork; -#endif diff --git a/labs/CompositionCollectionView/src/Layout.cs b/labs/CompositionCollectionView/src/Layout.cs index 3ee4f65f0..5a8cf177e 100644 --- a/labs/CompositionCollectionView/src/Layout.cs +++ b/labs/CompositionCollectionView/src/Layout.cs @@ -7,20 +7,9 @@ using System.Linq; using System.Numerics; using System.Threading.Tasks; -#if WINAPPSDK -using Microsoft.UI.Composition; -using Microsoft.UI.Xaml; -using Microsoft.UI.Xaml.Controls; -using Microsoft.UI.Xaml.Hosting; -#else -using Windows.UI.Composition; -using Windows.UI.Xaml; -using Windows.UI.Xaml.Controls; -using Windows.UI.Xaml.Hosting; -using static CommunityToolkit.Labs.WinUI.CompositionCollectionView.AnimationConstants; -#endif - -namespace CommunityToolkit.Labs.WinUI.CompositionCollectionView; +using static CommunityToolkit.Labs.WinUI.AnimationConstants; + +namespace CommunityToolkit.Labs.WinUI; public interface ILayout { Action? LayoutReplaced { get; set; } @@ -28,12 +17,11 @@ public interface ILayout void Activate(Panel panel); } -#if !WINAPPSDK -public abstract partial class Layout : ILayout, IDisposable +public abstract partial class CompositionCollectionLayout : ILayout, IDisposable where TId :notnull { public enum ElementAlignment { Start, Center, End }; - public Layout(Func elementFactory, Action? log) + public CompositionCollectionLayout(Func elementFactory, Action? log) { ElementFactory = elementFactory; _log = log; @@ -43,7 +31,7 @@ public Layout(Func elementFactory, Action? log) AnimatableNodes = new AnimatableCompositionNodeSet(compositor); } - public Layout(Layout sourceLayout) + public CompositionCollectionLayout(CompositionCollectionLayout sourceLayout) { ParentLayout = sourceLayout; @@ -124,7 +112,7 @@ private void RootSizeChanged(object sender, SizeChangedEventArgs e) public Action? LayoutReplaced { get; set; } //Public methods - public T TransitionTo(Func, T> factory) where T : Layout + public T TransitionTo(Func, T> factory) where T : CompositionCollectionLayout { System.Diagnostics.Debug.Assert(IsActive); @@ -280,9 +268,9 @@ private UIRoot GetVisualProperties() //private PointerEventHandler? _rootPointerCaptureLostHandler; - public Layout? ParentLayout { get; private set; } + public CompositionCollectionLayout? ParentLayout { get; private set; } - protected List> _behaviors = new List>(); + protected List> _behaviors = new List>(); //internal static Dictionary> ActiveTouchPointers { get; } = new(); @@ -483,7 +471,7 @@ public record Transition(uint Length, CompositionEasingFunction EasingFunction); public virtual ElementAlignment HorizontalAlignment { get; set; } - protected void AddBehavior(LayoutBehavior behavior) + protected void AddBehavior(CompositionCollectionLayoutBehavior behavior) { if (IsActive) { @@ -492,13 +480,13 @@ protected void AddBehavior(LayoutBehavior behavior) _behaviors.Add(behavior); } - public T GetBehavior() where T : LayoutBehavior => + public T GetBehavior() where T : CompositionCollectionLayoutBehavior => _behaviors.OfType().First(); - public T? TryGetBehavior() where T : LayoutBehavior => + public T? TryGetBehavior() where T : CompositionCollectionLayoutBehavior => _behaviors.OfType().FirstOrDefault(); - protected void RemoveBehavior(LayoutBehavior behavior) + protected void RemoveBehavior(CompositionCollectionLayoutBehavior behavior) { _behaviors.Remove(behavior); } @@ -546,4 +534,3 @@ public void Dispose() GC.SuppressFinalize(this); } } -#endif diff --git a/labs/CompositionCollectionView/src/Themes/Generic.xaml b/labs/CompositionCollectionView/src/Themes/Generic.xaml index ceaa11597..1c551333b 100644 --- a/labs/CompositionCollectionView/src/Themes/Generic.xaml +++ b/labs/CompositionCollectionView/src/Themes/Generic.xaml @@ -1,12 +1,11 @@ - - - + + + + diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/CompositionCollectionView.Tests.projitems b/components/CompositionCollectionView/tests/CompositionCollectionView.Tests.projitems similarity index 100% rename from labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/CompositionCollectionView.Tests.projitems rename to components/CompositionCollectionView/tests/CompositionCollectionView.Tests.projitems diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/CompositionCollectionView.Tests.shproj b/components/CompositionCollectionView/tests/CompositionCollectionView.Tests.shproj similarity index 98% rename from labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/CompositionCollectionView.Tests.shproj rename to components/CompositionCollectionView/tests/CompositionCollectionView.Tests.shproj index 7fdd3efc8..90c42dc27 100644 --- a/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/CompositionCollectionView.Tests.shproj +++ b/components/CompositionCollectionView/tests/CompositionCollectionView.Tests.shproj @@ -1,13 +1,13 @@ - - - - A3D47776-AA76-4032-B5CC-68A25B06796C - 14.0 - - - - - - - - + + + + A3D47776-AA76-4032-B5CC-68A25B06796C + 14.0 + + + + + + + + diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/ExampleCompositionCollectionViewTestClass.cs b/components/CompositionCollectionView/tests/ExampleCompositionCollectionViewTestClass.cs similarity index 100% rename from labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/ExampleCompositionCollectionViewTestClass.cs rename to components/CompositionCollectionView/tests/ExampleCompositionCollectionViewTestClass.cs diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/ExampleCompositionCollectionViewTestPage.xaml b/components/CompositionCollectionView/tests/ExampleCompositionCollectionViewTestPage.xaml similarity index 98% rename from labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/ExampleCompositionCollectionViewTestPage.xaml rename to components/CompositionCollectionView/tests/ExampleCompositionCollectionViewTestPage.xaml index 57231dd50..09a72853a 100644 --- a/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/ExampleCompositionCollectionViewTestPage.xaml +++ b/components/CompositionCollectionView/tests/ExampleCompositionCollectionViewTestPage.xaml @@ -1,14 +1,14 @@ - - - - - - - + + + + + + + diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/ExampleCompositionCollectionViewTestPage.xaml.cs b/components/CompositionCollectionView/tests/ExampleCompositionCollectionViewTestPage.xaml.cs similarity index 100% rename from labs/CompositionCollectionView/tests/CompositionCollectionView.Tests/ExampleCompositionCollectionViewTestPage.xaml.cs rename to components/CompositionCollectionView/tests/ExampleCompositionCollectionViewTestPage.xaml.cs diff --git a/labs/CompositionCollectionView/CompositionCollectionView.sln b/labs/CompositionCollectionView/CompositionCollectionView.sln deleted file mode 100644 index 05263fa31..000000000 --- a/labs/CompositionCollectionView/CompositionCollectionView.sln +++ /dev/null @@ -1,310 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.0.31919.166 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CommunityToolkit.Labs.WinUI.CompositionCollectionView", "src\CommunityToolkit.Labs.WinUI.CompositionCollectionView.csproj", "{43B832EE-C2B5-4648-B7EE-DD35D4B58CEC}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CompositionCollectionView.Uwp", "samples\CompositionCollectionView.Uwp\CompositionCollectionView.Uwp.csproj", "{1FF91978-D8BA-4528-8CC6-D9AB79E734FB}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompositionCollectionView.Wasm", "samples\CompositionCollectionView.Wasm\CompositionCollectionView.Wasm.csproj", "{16334921-9519-4D83-9EB0-A7DC4FB9F355}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompositionCollectionView.Samples", "samples\CompositionCollectionView.Samples\CompositionCollectionView.Samples.csproj", "{91DD91AC-9C40-4E84-AFD1-F1660BFDDB59}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Platforms", "Platforms", "{B8A02B6F-312F-4FF5-98D7-115C8635732B}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompositionCollectionView.WinAppSdk", "samples\CompositionCollectionView.WinAppSdk\CompositionCollectionView.WinAppSdk.csproj", "{77778DBE-302C-4004-B939-1ADB15E421B0}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CommunityToolkit.Labs.Core.SourceGenerators", "..\..\common\CommunityToolkit.Labs.Core.SourceGenerators\CommunityToolkit.Labs.Core.SourceGenerators.csproj", "{66E6DA8A-FEFC-4221-A476-4314A4D692F6}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CommunityToolkit.Labs.Core.SourceGenerators.XamlNamedPropertyRelay", "..\..\common\CommunityToolkit.Labs.Core.SourceGenerators.XamlNamedPropertyRelay\CommunityToolkit.Labs.Core.SourceGenerators.XamlNamedPropertyRelay.csproj", "{7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{CCE58C30-A3E9-4058-83DC-0FB6197F4E07}" -EndProject -Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "CompositionCollectionView.Tests", "tests\CompositionCollectionView.Tests\CompositionCollectionView.Tests.shproj", "{A3D47776-AA76-4032-B5CC-68A25B06796C}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompositionCollectionView.Tests.WinAppSdk", "tests\CompositionCollectionView.Tests.WinAppSdk\CompositionCollectionView.Tests.WinAppSdk.csproj", "{2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CompositionCollectionView.Tests.Uwp", "tests\CompositionCollectionView.Tests.Uwp\CompositionCollectionView.Tests.Uwp.csproj", "{3EF11E40-143F-437E-B4C7-3900D5DCF095}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Labs Dependencies", "Labs Dependencies", "{1CB5B668-FD44-4524-8A28-F7057AEC9DF3}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CommunityToolkit.Labs.Core.SourceGenerators.LabsUITestMethod", "..\..\common\CommunityToolkit.Labs.Core.SourceGenerators.LabsUITestMethod\CommunityToolkit.Labs.Core.SourceGenerators.LabsUITestMethod.csproj", "{79F79471-9947-45F5-81FE-4EBE2B8D0B1D}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|ARM = Debug|ARM - Debug|ARM64 = Debug|ARM64 - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Any CPU = Release|Any CPU - Release|ARM = Release|ARM - Release|ARM64 = Release|ARM64 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {43B832EE-C2B5-4648-B7EE-DD35D4B58CEC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {43B832EE-C2B5-4648-B7EE-DD35D4B58CEC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {43B832EE-C2B5-4648-B7EE-DD35D4B58CEC}.Debug|ARM.ActiveCfg = Debug|Any CPU - {43B832EE-C2B5-4648-B7EE-DD35D4B58CEC}.Debug|ARM.Build.0 = Debug|Any CPU - {43B832EE-C2B5-4648-B7EE-DD35D4B58CEC}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {43B832EE-C2B5-4648-B7EE-DD35D4B58CEC}.Debug|ARM64.Build.0 = Debug|Any CPU - {43B832EE-C2B5-4648-B7EE-DD35D4B58CEC}.Debug|x64.ActiveCfg = Debug|Any CPU - {43B832EE-C2B5-4648-B7EE-DD35D4B58CEC}.Debug|x64.Build.0 = Debug|Any CPU - {43B832EE-C2B5-4648-B7EE-DD35D4B58CEC}.Debug|x86.ActiveCfg = Debug|Any CPU - {43B832EE-C2B5-4648-B7EE-DD35D4B58CEC}.Debug|x86.Build.0 = Debug|Any CPU - {43B832EE-C2B5-4648-B7EE-DD35D4B58CEC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {43B832EE-C2B5-4648-B7EE-DD35D4B58CEC}.Release|Any CPU.Build.0 = Release|Any CPU - {43B832EE-C2B5-4648-B7EE-DD35D4B58CEC}.Release|ARM.ActiveCfg = Release|Any CPU - {43B832EE-C2B5-4648-B7EE-DD35D4B58CEC}.Release|ARM.Build.0 = Release|Any CPU - {43B832EE-C2B5-4648-B7EE-DD35D4B58CEC}.Release|ARM64.ActiveCfg = Release|Any CPU - {43B832EE-C2B5-4648-B7EE-DD35D4B58CEC}.Release|ARM64.Build.0 = Release|Any CPU - {43B832EE-C2B5-4648-B7EE-DD35D4B58CEC}.Release|x64.ActiveCfg = Release|Any CPU - {43B832EE-C2B5-4648-B7EE-DD35D4B58CEC}.Release|x64.Build.0 = Release|Any CPU - {43B832EE-C2B5-4648-B7EE-DD35D4B58CEC}.Release|x86.ActiveCfg = Release|Any CPU - {43B832EE-C2B5-4648-B7EE-DD35D4B58CEC}.Release|x86.Build.0 = Release|Any CPU - {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Debug|Any CPU.ActiveCfg = Debug|x64 - {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Debug|Any CPU.Build.0 = Debug|x64 - {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Debug|Any CPU.Deploy.0 = Debug|x64 - {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Debug|ARM.ActiveCfg = Debug|ARM - {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Debug|ARM.Build.0 = Debug|ARM - {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Debug|ARM.Deploy.0 = Debug|ARM - {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Debug|ARM64.Build.0 = Debug|ARM64 - {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Debug|ARM64.Deploy.0 = Debug|ARM64 - {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Debug|x64.ActiveCfg = Debug|x64 - {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Debug|x64.Build.0 = Debug|x64 - {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Debug|x64.Deploy.0 = Debug|x64 - {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Debug|x86.ActiveCfg = Debug|x86 - {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Debug|x86.Build.0 = Debug|x86 - {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Debug|x86.Deploy.0 = Debug|x86 - {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Release|Any CPU.ActiveCfg = Release|x64 - {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Release|Any CPU.Build.0 = Release|x64 - {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Release|Any CPU.Deploy.0 = Release|x64 - {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Release|ARM.ActiveCfg = Release|ARM - {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Release|ARM.Build.0 = Release|ARM - {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Release|ARM.Deploy.0 = Release|ARM - {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Release|ARM64.ActiveCfg = Release|ARM64 - {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Release|ARM64.Build.0 = Release|ARM64 - {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Release|ARM64.Deploy.0 = Release|ARM64 - {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Release|x64.ActiveCfg = Release|x64 - {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Release|x64.Build.0 = Release|x64 - {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Release|x64.Deploy.0 = Release|x64 - {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Release|x86.ActiveCfg = Release|x86 - {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Release|x86.Build.0 = Release|x86 - {1FF91978-D8BA-4528-8CC6-D9AB79E734FB}.Release|x86.Deploy.0 = Release|x86 - {16334921-9519-4D83-9EB0-A7DC4FB9F355}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {16334921-9519-4D83-9EB0-A7DC4FB9F355}.Debug|Any CPU.Build.0 = Debug|Any CPU - {16334921-9519-4D83-9EB0-A7DC4FB9F355}.Debug|ARM.ActiveCfg = Debug|Any CPU - {16334921-9519-4D83-9EB0-A7DC4FB9F355}.Debug|ARM.Build.0 = Debug|Any CPU - {16334921-9519-4D83-9EB0-A7DC4FB9F355}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {16334921-9519-4D83-9EB0-A7DC4FB9F355}.Debug|ARM64.Build.0 = Debug|Any CPU - {16334921-9519-4D83-9EB0-A7DC4FB9F355}.Debug|x64.ActiveCfg = Debug|Any CPU - {16334921-9519-4D83-9EB0-A7DC4FB9F355}.Debug|x64.Build.0 = Debug|Any CPU - {16334921-9519-4D83-9EB0-A7DC4FB9F355}.Debug|x86.ActiveCfg = Debug|Any CPU - {16334921-9519-4D83-9EB0-A7DC4FB9F355}.Debug|x86.Build.0 = Debug|Any CPU - {16334921-9519-4D83-9EB0-A7DC4FB9F355}.Release|Any CPU.ActiveCfg = Release|Any CPU - {16334921-9519-4D83-9EB0-A7DC4FB9F355}.Release|Any CPU.Build.0 = Release|Any CPU - {16334921-9519-4D83-9EB0-A7DC4FB9F355}.Release|ARM.ActiveCfg = Release|Any CPU - {16334921-9519-4D83-9EB0-A7DC4FB9F355}.Release|ARM.Build.0 = Release|Any CPU - {16334921-9519-4D83-9EB0-A7DC4FB9F355}.Release|ARM64.ActiveCfg = Release|Any CPU - {16334921-9519-4D83-9EB0-A7DC4FB9F355}.Release|ARM64.Build.0 = Release|Any CPU - {16334921-9519-4D83-9EB0-A7DC4FB9F355}.Release|x64.ActiveCfg = Release|Any CPU - {16334921-9519-4D83-9EB0-A7DC4FB9F355}.Release|x64.Build.0 = Release|Any CPU - {16334921-9519-4D83-9EB0-A7DC4FB9F355}.Release|x86.ActiveCfg = Release|Any CPU - {16334921-9519-4D83-9EB0-A7DC4FB9F355}.Release|x86.Build.0 = Release|Any CPU - {91DD91AC-9C40-4E84-AFD1-F1660BFDDB59}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {91DD91AC-9C40-4E84-AFD1-F1660BFDDB59}.Debug|Any CPU.Build.0 = Debug|Any CPU - {91DD91AC-9C40-4E84-AFD1-F1660BFDDB59}.Debug|ARM.ActiveCfg = Debug|Any CPU - {91DD91AC-9C40-4E84-AFD1-F1660BFDDB59}.Debug|ARM.Build.0 = Debug|Any CPU - {91DD91AC-9C40-4E84-AFD1-F1660BFDDB59}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {91DD91AC-9C40-4E84-AFD1-F1660BFDDB59}.Debug|ARM64.Build.0 = Debug|Any CPU - {91DD91AC-9C40-4E84-AFD1-F1660BFDDB59}.Debug|x64.ActiveCfg = Debug|Any CPU - {91DD91AC-9C40-4E84-AFD1-F1660BFDDB59}.Debug|x64.Build.0 = Debug|Any CPU - {91DD91AC-9C40-4E84-AFD1-F1660BFDDB59}.Debug|x86.ActiveCfg = Debug|Any CPU - {91DD91AC-9C40-4E84-AFD1-F1660BFDDB59}.Debug|x86.Build.0 = Debug|Any CPU - {91DD91AC-9C40-4E84-AFD1-F1660BFDDB59}.Release|Any CPU.ActiveCfg = Release|Any CPU - {91DD91AC-9C40-4E84-AFD1-F1660BFDDB59}.Release|Any CPU.Build.0 = Release|Any CPU - {91DD91AC-9C40-4E84-AFD1-F1660BFDDB59}.Release|ARM.ActiveCfg = Release|Any CPU - {91DD91AC-9C40-4E84-AFD1-F1660BFDDB59}.Release|ARM.Build.0 = Release|Any CPU - {91DD91AC-9C40-4E84-AFD1-F1660BFDDB59}.Release|ARM64.ActiveCfg = Release|Any CPU - {91DD91AC-9C40-4E84-AFD1-F1660BFDDB59}.Release|ARM64.Build.0 = Release|Any CPU - {91DD91AC-9C40-4E84-AFD1-F1660BFDDB59}.Release|x64.ActiveCfg = Release|Any CPU - {91DD91AC-9C40-4E84-AFD1-F1660BFDDB59}.Release|x64.Build.0 = Release|Any CPU - {91DD91AC-9C40-4E84-AFD1-F1660BFDDB59}.Release|x86.ActiveCfg = Release|Any CPU - {91DD91AC-9C40-4E84-AFD1-F1660BFDDB59}.Release|x86.Build.0 = Release|Any CPU - {77778DBE-302C-4004-B939-1ADB15E421B0}.Debug|Any CPU.ActiveCfg = Debug|x64 - {77778DBE-302C-4004-B939-1ADB15E421B0}.Debug|Any CPU.Build.0 = Debug|x64 - {77778DBE-302C-4004-B939-1ADB15E421B0}.Debug|Any CPU.Deploy.0 = Debug|x64 - {77778DBE-302C-4004-B939-1ADB15E421B0}.Debug|ARM.ActiveCfg = Debug|x64 - {77778DBE-302C-4004-B939-1ADB15E421B0}.Debug|ARM.Build.0 = Debug|x64 - {77778DBE-302C-4004-B939-1ADB15E421B0}.Debug|ARM.Deploy.0 = Debug|x64 - {77778DBE-302C-4004-B939-1ADB15E421B0}.Debug|ARM64.ActiveCfg = Debug|arm64 - {77778DBE-302C-4004-B939-1ADB15E421B0}.Debug|ARM64.Build.0 = Debug|arm64 - {77778DBE-302C-4004-B939-1ADB15E421B0}.Debug|ARM64.Deploy.0 = Debug|arm64 - {77778DBE-302C-4004-B939-1ADB15E421B0}.Debug|x64.ActiveCfg = Debug|x64 - {77778DBE-302C-4004-B939-1ADB15E421B0}.Debug|x64.Build.0 = Debug|x64 - {77778DBE-302C-4004-B939-1ADB15E421B0}.Debug|x64.Deploy.0 = Debug|x64 - {77778DBE-302C-4004-B939-1ADB15E421B0}.Debug|x86.ActiveCfg = Debug|x86 - {77778DBE-302C-4004-B939-1ADB15E421B0}.Debug|x86.Build.0 = Debug|x86 - {77778DBE-302C-4004-B939-1ADB15E421B0}.Debug|x86.Deploy.0 = Debug|x86 - {77778DBE-302C-4004-B939-1ADB15E421B0}.Release|Any CPU.ActiveCfg = Release|x64 - {77778DBE-302C-4004-B939-1ADB15E421B0}.Release|Any CPU.Build.0 = Release|x64 - {77778DBE-302C-4004-B939-1ADB15E421B0}.Release|Any CPU.Deploy.0 = Release|x64 - {77778DBE-302C-4004-B939-1ADB15E421B0}.Release|ARM.ActiveCfg = Release|x64 - {77778DBE-302C-4004-B939-1ADB15E421B0}.Release|ARM.Build.0 = Release|x64 - {77778DBE-302C-4004-B939-1ADB15E421B0}.Release|ARM.Deploy.0 = Release|x64 - {77778DBE-302C-4004-B939-1ADB15E421B0}.Release|ARM64.ActiveCfg = Release|arm64 - {77778DBE-302C-4004-B939-1ADB15E421B0}.Release|ARM64.Build.0 = Release|arm64 - {77778DBE-302C-4004-B939-1ADB15E421B0}.Release|ARM64.Deploy.0 = Release|arm64 - {77778DBE-302C-4004-B939-1ADB15E421B0}.Release|x64.ActiveCfg = Release|x64 - {77778DBE-302C-4004-B939-1ADB15E421B0}.Release|x64.Build.0 = Release|x64 - {77778DBE-302C-4004-B939-1ADB15E421B0}.Release|x64.Deploy.0 = Release|x64 - {77778DBE-302C-4004-B939-1ADB15E421B0}.Release|x86.ActiveCfg = Release|x86 - {77778DBE-302C-4004-B939-1ADB15E421B0}.Release|x86.Build.0 = Release|x86 - {77778DBE-302C-4004-B939-1ADB15E421B0}.Release|x86.Deploy.0 = Release|x86 - {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Debug|ARM.ActiveCfg = Debug|Any CPU - {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Debug|ARM.Build.0 = Debug|Any CPU - {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Debug|ARM64.Build.0 = Debug|Any CPU - {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Debug|x64.ActiveCfg = Debug|Any CPU - {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Debug|x64.Build.0 = Debug|Any CPU - {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Debug|x86.ActiveCfg = Debug|Any CPU - {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Debug|x86.Build.0 = Debug|Any CPU - {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Release|Any CPU.Build.0 = Release|Any CPU - {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Release|ARM.ActiveCfg = Release|Any CPU - {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Release|ARM.Build.0 = Release|Any CPU - {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Release|ARM64.ActiveCfg = Release|Any CPU - {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Release|ARM64.Build.0 = Release|Any CPU - {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Release|x64.ActiveCfg = Release|Any CPU - {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Release|x64.Build.0 = Release|Any CPU - {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Release|x86.ActiveCfg = Release|Any CPU - {66E6DA8A-FEFC-4221-A476-4314A4D692F6}.Release|x86.Build.0 = Release|Any CPU - {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Debug|ARM.ActiveCfg = Debug|Any CPU - {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Debug|ARM.Build.0 = Debug|Any CPU - {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Debug|ARM64.Build.0 = Debug|Any CPU - {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Debug|x64.ActiveCfg = Debug|Any CPU - {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Debug|x64.Build.0 = Debug|Any CPU - {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Debug|x86.ActiveCfg = Debug|Any CPU - {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Debug|x86.Build.0 = Debug|Any CPU - {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Release|Any CPU.Build.0 = Release|Any CPU - {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Release|ARM.ActiveCfg = Release|Any CPU - {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Release|ARM.Build.0 = Release|Any CPU - {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Release|ARM64.ActiveCfg = Release|Any CPU - {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Release|ARM64.Build.0 = Release|Any CPU - {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Release|x64.ActiveCfg = Release|Any CPU - {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Release|x64.Build.0 = Release|Any CPU - {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Release|x86.ActiveCfg = Release|Any CPU - {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91}.Release|x86.Build.0 = Release|Any CPU - {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Debug|Any CPU.ActiveCfg = Debug|x64 - {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Debug|Any CPU.Build.0 = Debug|x64 - {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Debug|Any CPU.Deploy.0 = Debug|x64 - {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Debug|ARM.ActiveCfg = Debug|x64 - {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Debug|ARM.Build.0 = Debug|x64 - {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Debug|ARM.Deploy.0 = Debug|x64 - {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Debug|ARM64.ActiveCfg = Debug|arm64 - {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Debug|ARM64.Build.0 = Debug|arm64 - {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Debug|ARM64.Deploy.0 = Debug|arm64 - {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Debug|x64.ActiveCfg = Debug|x64 - {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Debug|x64.Build.0 = Debug|x64 - {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Debug|x64.Deploy.0 = Debug|x64 - {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Debug|x86.ActiveCfg = Debug|x86 - {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Debug|x86.Build.0 = Debug|x86 - {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Debug|x86.Deploy.0 = Debug|x86 - {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Release|Any CPU.ActiveCfg = Release|x64 - {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Release|Any CPU.Build.0 = Release|x64 - {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Release|Any CPU.Deploy.0 = Release|x64 - {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Release|ARM.ActiveCfg = Release|x64 - {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Release|ARM.Build.0 = Release|x64 - {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Release|ARM.Deploy.0 = Release|x64 - {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Release|ARM64.ActiveCfg = Release|arm64 - {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Release|ARM64.Build.0 = Release|arm64 - {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Release|ARM64.Deploy.0 = Release|arm64 - {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Release|x64.ActiveCfg = Release|x64 - {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Release|x64.Build.0 = Release|x64 - {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Release|x64.Deploy.0 = Release|x64 - {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Release|x86.ActiveCfg = Release|x86 - {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Release|x86.Build.0 = Release|x86 - {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3}.Release|x86.Deploy.0 = Release|x86 - {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Debug|Any CPU.ActiveCfg = Debug|x64 - {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Debug|Any CPU.Build.0 = Debug|x64 - {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Debug|Any CPU.Deploy.0 = Debug|x64 - {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Debug|ARM.ActiveCfg = Debug|ARM - {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Debug|ARM.Build.0 = Debug|ARM - {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Debug|ARM.Deploy.0 = Debug|ARM - {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Debug|ARM64.Build.0 = Debug|ARM64 - {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Debug|ARM64.Deploy.0 = Debug|ARM64 - {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Debug|x64.ActiveCfg = Debug|x64 - {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Debug|x64.Build.0 = Debug|x64 - {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Debug|x64.Deploy.0 = Debug|x64 - {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Debug|x86.ActiveCfg = Debug|x86 - {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Debug|x86.Build.0 = Debug|x86 - {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Debug|x86.Deploy.0 = Debug|x86 - {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Release|Any CPU.ActiveCfg = Release|x64 - {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Release|Any CPU.Build.0 = Release|x64 - {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Release|Any CPU.Deploy.0 = Release|x64 - {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Release|ARM.ActiveCfg = Release|ARM - {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Release|ARM.Build.0 = Release|ARM - {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Release|ARM.Deploy.0 = Release|ARM - {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Release|ARM64.ActiveCfg = Release|ARM64 - {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Release|ARM64.Build.0 = Release|ARM64 - {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Release|ARM64.Deploy.0 = Release|ARM64 - {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Release|x64.ActiveCfg = Release|x64 - {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Release|x64.Build.0 = Release|x64 - {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Release|x64.Deploy.0 = Release|x64 - {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Release|x86.ActiveCfg = Release|x86 - {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Release|x86.Build.0 = Release|x86 - {3EF11E40-143F-437E-B4C7-3900D5DCF095}.Release|x86.Deploy.0 = Release|x86 - {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Debug|ARM.ActiveCfg = Debug|Any CPU - {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Debug|ARM.Build.0 = Debug|Any CPU - {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Debug|ARM64.Build.0 = Debug|Any CPU - {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Debug|x64.ActiveCfg = Debug|Any CPU - {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Debug|x64.Build.0 = Debug|Any CPU - {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Debug|x86.ActiveCfg = Debug|Any CPU - {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Debug|x86.Build.0 = Debug|Any CPU - {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Release|Any CPU.Build.0 = Release|Any CPU - {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Release|ARM.ActiveCfg = Release|Any CPU - {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Release|ARM.Build.0 = Release|Any CPU - {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Release|ARM64.ActiveCfg = Release|Any CPU - {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Release|ARM64.Build.0 = Release|Any CPU - {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Release|x64.ActiveCfg = Release|Any CPU - {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Release|x64.Build.0 = Release|Any CPU - {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Release|x86.ActiveCfg = Release|Any CPU - {79F79471-9947-45F5-81FE-4EBE2B8D0B1D}.Release|x86.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {1FF91978-D8BA-4528-8CC6-D9AB79E734FB} = {B8A02B6F-312F-4FF5-98D7-115C8635732B} - {16334921-9519-4D83-9EB0-A7DC4FB9F355} = {B8A02B6F-312F-4FF5-98D7-115C8635732B} - {77778DBE-302C-4004-B939-1ADB15E421B0} = {B8A02B6F-312F-4FF5-98D7-115C8635732B} - {66E6DA8A-FEFC-4221-A476-4314A4D692F6} = {1CB5B668-FD44-4524-8A28-F7057AEC9DF3} - {7A1E5FBF-B51A-4B56-8EA3-6AB56A7E9D91} = {1CB5B668-FD44-4524-8A28-F7057AEC9DF3} - {2F6E208D-6E57-46E5-95D6-BDDBF8404CB3} = {CCE58C30-A3E9-4058-83DC-0FB6197F4E07} - {3EF11E40-143F-437E-B4C7-3900D5DCF095} = {CCE58C30-A3E9-4058-83DC-0FB6197F4E07} - {79F79471-9947-45F5-81FE-4EBE2B8D0B1D} = {1CB5B668-FD44-4524-8A28-F7057AEC9DF3} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {69A3A187-4290-4A0A-9FD6-F491BDAAC5BF} - EndGlobalSection - GlobalSection(SharedMSBuildProjectFiles) = preSolution - ..\..\common\CommunityToolkit.Labs.Shared\CommunityToolkit.Labs.Shared.projitems*{1ff91978-d8ba-4528-8cc6-d9ab79e734fb}*SharedItemsImports = 4 - tests\CompositionCollectionView.Tests\CompositionCollectionView.Tests.projitems*{2f6e208d-6e57-46e5-95d6-bddbf8404cb3}*SharedItemsImports = 5 - tests\CompositionCollectionView.Tests\CompositionCollectionView.Tests.projitems*{3ef11e40-143f-437e-b4c7-3900d5dcf095}*SharedItemsImports = 4 - tests\CompositionCollectionView.Tests\CompositionCollectionView.Tests.projitems*{a3d47776-aa76-4032-b5cc-68a25b06796c}*SharedItemsImports = 13 - EndGlobalSection -EndGlobal diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionView.Samples.csproj b/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionView.Samples.csproj deleted file mode 100644 index 915e72726..000000000 --- a/labs/CompositionCollectionView/samples/CompositionCollectionView.Samples/CompositionCollectionView.Samples.csproj +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - CompositionCollectionViewExperiment.Samples - CompositionCollectionViewExperiment.Samples - - - - - - - - - - - - - - - diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Uwp/CompositionCollectionView.Uwp.csproj b/labs/CompositionCollectionView/samples/CompositionCollectionView.Uwp/CompositionCollectionView.Uwp.csproj deleted file mode 100644 index eb380c55e..000000000 --- a/labs/CompositionCollectionView/samples/CompositionCollectionView.Uwp/CompositionCollectionView.Uwp.csproj +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - - - true - false - false - false - false - false - false - false - true - false - false - false - false - false - false - false - - - - - - - - - - - CompositionCollectionViewExperiment.Samples - CompositionCollectionViewExperiment.Samples.Uwp - {1FF91978-D8BA-4528-8CC6-D9AB79E734FB} - - - - - - - Designer - - - - - {43B832EE-C2B5-4648-B7EE-DD35D4B58CEC} - CommunityToolkit.Labs.WinUI.CompositionCollectionView - - - {91DD91AC-9C40-4E84-AFD1-F1660BFDDB59} - CompositionCollectionView.Sample - - - - - \ No newline at end of file diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Uwp/Package.appxmanifest b/labs/CompositionCollectionView/samples/CompositionCollectionView.Uwp/Package.appxmanifest deleted file mode 100644 index 2148ed375..000000000 --- a/labs/CompositionCollectionView/samples/CompositionCollectionView.Uwp/Package.appxmanifest +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - CommunityToolkit Labs: CompositionCollectionView Samples (UWP) - CommunityToolkit - Assets\StoreLogo.png - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Uwp/Properties/AssemblyInfo.cs b/labs/CompositionCollectionView/samples/CompositionCollectionView.Uwp/Properties/AssemblyInfo.cs deleted file mode 100644 index 0851e6170..000000000 --- a/labs/CompositionCollectionView/samples/CompositionCollectionView.Uwp/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,33 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("CommunityToolkit.Labs.Uwp.Samples.CompositionCollectionView")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany(".NET Foundation")] -[assembly: AssemblyProduct("CommunityToolkit.Labs.Uwp.Samples.CompositionCollectionView")] -[assembly: AssemblyCopyright("Copyright © .NET Foundation 2022")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] -[assembly: ComVisible(false)] diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Uwp/Properties/Default.rd.xml b/labs/CompositionCollectionView/samples/CompositionCollectionView.Uwp/Properties/Default.rd.xml deleted file mode 100644 index af00722cd..000000000 --- a/labs/CompositionCollectionView/samples/CompositionCollectionView.Uwp/Properties/Default.rd.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/CompositionCollectionView.Wasm.csproj b/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/CompositionCollectionView.Wasm.csproj deleted file mode 100644 index 6f62190a3..000000000 --- a/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/CompositionCollectionView.Wasm.csproj +++ /dev/null @@ -1,41 +0,0 @@ - - - - - true - true - true - false - false - false - false - false - false - false - false - false - false - false - false - false - - - - - - - - - - - - - - - - - - - - - diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/Program.cs b/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/Program.cs deleted file mode 100644 index 41c789347..000000000 --- a/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/Program.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using CommunityToolkit.Labs.Shared; - -namespace CompositionCollectionViewExperiment.Samples.Wasm; - -public class Program -{ - private static App? _app; - - static int Main(string[] args) - { - Application.Start(_ => _app = new App()); - - return 0; - } -} diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/Properties/launchSettings.json b/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/Properties/launchSettings.json deleted file mode 100644 index 33b0e52e0..000000000 --- a/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/Properties/launchSettings.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:50720/", - "sslPort": 44326 - } - }, - "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "CompositionCollectionView.Wasm": { - "commandName": "Project", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - }, - "applicationUrl": "https://localhost:5001;http://localhost:5000" - } - } -} diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/WasmCSS/Fonts.css b/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/WasmCSS/Fonts.css deleted file mode 100644 index 56618162a..000000000 --- a/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/WasmCSS/Fonts.css +++ /dev/null @@ -1,27 +0,0 @@ -/** - When adding fonts here, make sure to add them using a base64 data uri, otherwise - fonts loading are delayed, and text may get displayed incorrectly. -*/ - -@font-face { - font-family: "Symbols"; - /* uno-fluentui-assets.woff2 */ - src: url(data:application/x-font-woff;charset=utf-8;base64,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)format('woff'); -} - - -/* Workaround for uno issue https://github.com/unoplatform/uno/issues/693 */ -body::before { - font-family: 'Symbols'; - background: transparent; - content: ""; - opacity: 0; - pointer-events: none; - position: absolute; -} - -/* https://github.com/unoplatform/uno/issues/4304 */ -@font-face { - font-family: 'Segoe UI'; - src: local('system-ui'), local('Segoe UI'), local('-apple-system'), local('BlinkMacSystemFont'), local('Inter'), local('Cantarell'), local('Ubuntu'), local('Roboto'), local('Open Sans'), local('Noto Sans'), local('Helvetica Neue'), local('sans-serif'); -} \ No newline at end of file diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/WasmScripts/AppManifest.js b/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/WasmScripts/AppManifest.js deleted file mode 100644 index 185d1d38d..000000000 --- a/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/WasmScripts/AppManifest.js +++ /dev/null @@ -1,5 +0,0 @@ -var UnoAppManifest = { - splashScreenImage: "Assets/SplashScreen.png", - splashScreenColor: "#fff", - displayName: "Labs: CompositionCollectionView" -} diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/wwwroot/web.config b/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/wwwroot/web.config deleted file mode 100644 index 8f5a860f5..000000000 --- a/labs/CompositionCollectionView/samples/CompositionCollectionView.Wasm/wwwroot/web.config +++ /dev/null @@ -1,78 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.WinAppSdk/CompositionCollectionView.WinAppSdk.csproj b/labs/CompositionCollectionView/samples/CompositionCollectionView.WinAppSdk/CompositionCollectionView.WinAppSdk.csproj deleted file mode 100644 index cd5e53a62..000000000 --- a/labs/CompositionCollectionView/samples/CompositionCollectionView.WinAppSdk/CompositionCollectionView.WinAppSdk.csproj +++ /dev/null @@ -1,46 +0,0 @@ - - - - - true - false - false - false - false - false - false - false - false - true - false - false - false - false - false - false - - - - - - - - - - - CompositionCollectionViewExperiment.Samples - CompositionCollectionViewExperiment.Samples.WinAppSdk - - - - - - - - - - - - diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.WinAppSdk/Package.appxmanifest b/labs/CompositionCollectionView/samples/CompositionCollectionView.WinAppSdk/Package.appxmanifest deleted file mode 100644 index 73268eaaf..000000000 --- a/labs/CompositionCollectionView/samples/CompositionCollectionView.WinAppSdk/Package.appxmanifest +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - CommunityToolkit Labs: CompositionCollectionView Samples (WinAppSdk) - CommunityToolkit - Assets\StoreLogo.png - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.WinAppSdk/Properties/launchSettings.json b/labs/CompositionCollectionView/samples/CompositionCollectionView.WinAppSdk/Properties/launchSettings.json deleted file mode 100644 index f06823289..000000000 --- a/labs/CompositionCollectionView/samples/CompositionCollectionView.WinAppSdk/Properties/launchSettings.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "profiles": { - "Local machine (Packaged)": { - "commandName": "MsixPackage" - }, - "Local machine (Unpackaged)": { - "commandName": "Project" - } - } -} \ No newline at end of file diff --git a/labs/CompositionCollectionView/samples/CompositionCollectionView.WinAppSdk/app.manifest b/labs/CompositionCollectionView/samples/CompositionCollectionView.WinAppSdk/app.manifest deleted file mode 100644 index 04ff2978a..000000000 --- a/labs/CompositionCollectionView/samples/CompositionCollectionView.WinAppSdk/app.manifest +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - true/PM - PerMonitorV2, PerMonitor - - - diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.Uwp/CompositionCollectionView.Tests.Uwp.csproj b/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.Uwp/CompositionCollectionView.Tests.Uwp.csproj deleted file mode 100644 index d9c24b038..000000000 --- a/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.Uwp/CompositionCollectionView.Tests.Uwp.csproj +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - true - - - - - - - - - - - {3EF11E40-143F-437E-B4C7-3900D5DCF095} - CompositionCollectionViewExperiment.Tests - CompositionCollectionViewExperiment.Tests.Uwp - $(VisualStudioVersion) - - - - - - Designer - - - - - Assets\LockScreenLogo.png - - - Assets\Square150x150Logo.png - - - Assets\Square44x44Logo.png - - - Assets\Square44x44Logo.targetsize-24_altform-unplated.png - - - Assets\StoreLogo.png - - - - - - - - - - - - - - - diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.Uwp/Package.appxmanifest b/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.Uwp/Package.appxmanifest deleted file mode 100644 index 8bd839a02..000000000 --- a/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.Uwp/Package.appxmanifest +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - CompositionCollectionViewExperiment.Tests.Uwp - CommunityToolkit - Assets\StoreLogo.png - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.Uwp/Properties/AssemblyInfo.cs b/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.Uwp/Properties/AssemblyInfo.cs deleted file mode 100644 index a86521f30..000000000 --- a/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.Uwp/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -[assembly: AssemblyTitle("CompositionCollectionViewExperiment.Tests.Uwp")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany(".NET Foundation")] -[assembly: AssemblyProduct("CompositionCollectionViewExperiment.Tests.Uwp")] -[assembly: AssemblyCopyright("Copyright © .NET Foundation 2022")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] -[assembly: AssemblyMetadata("TargetPlatform","UAP")] - -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] -[assembly: ComVisible(false)] \ No newline at end of file diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.Uwp/Properties/Default.rd.xml b/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.Uwp/Properties/Default.rd.xml deleted file mode 100644 index 996a8392a..000000000 --- a/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.Uwp/Properties/Default.rd.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.WinAppSdk/CompositionCollectionView.Tests.WinAppSdk.csproj b/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.WinAppSdk/CompositionCollectionView.Tests.WinAppSdk.csproj deleted file mode 100644 index d6dbf8579..000000000 --- a/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.WinAppSdk/CompositionCollectionView.Tests.WinAppSdk.csproj +++ /dev/null @@ -1,43 +0,0 @@ - - - - - true - - - - - - - - - - - CompositionCollectionViewExperiment.Tests - CompositionCollectionViewExperiment.Tests.WinAppSdk - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.WinAppSdk/Package.appxmanifest b/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.WinAppSdk/Package.appxmanifest deleted file mode 100644 index aa2818b44..000000000 --- a/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.WinAppSdk/Package.appxmanifest +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - CompositionCollectionViewExperiment.Tests.WinAppSdk - CommunityToolkit - Assets\StoreLogo.png - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.WinAppSdk/Properties/launchSettings.json b/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.WinAppSdk/Properties/launchSettings.json deleted file mode 100644 index b5d7775c6..000000000 --- a/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.WinAppSdk/Properties/launchSettings.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "profiles": { - "CompositionCollectionView.Tests.WinAppSdk (Package)": { - "commandName": "MsixPackage" - }, - "CompositionCollectionView.Tests.WinAppSdk (Unpackaged)": { - "commandName": "Project" - } - } -} diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.WinAppSdk/app.manifest b/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.WinAppSdk/app.manifest deleted file mode 100644 index 84b8521ee..000000000 --- a/labs/CompositionCollectionView/tests/CompositionCollectionView.Tests.WinAppSdk/app.manifest +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - true/PM - PerMonitorV2, PerMonitor - - - diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.Uwp/CompositionCollectionView.UnitTests.Uwp.csproj b/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.Uwp/CompositionCollectionView.UnitTests.Uwp.csproj deleted file mode 100644 index aee749fe9..000000000 --- a/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.Uwp/CompositionCollectionView.UnitTests.Uwp.csproj +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - {87F8E99E-6C8A-43BA-9FAC-F8FE49347FC2} - CompositionCollectionView.UnitTests - CompositionCollectionView.UnitTests.Uwp - $(VisualStudioVersion) - - - - - - - - - Designer - - - - - Assets\LockScreenLogo.scale-200.png - - - Assets\Square150x150Logo.scale-200.png - - - Assets\Square44x44Logo.scale-200.png - - - Assets\Square44x44Logo.targetsize-24_altform-unplated.png - - - Assets\StoreLogo.png - - - - - - - - - - - - diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.Uwp/Package.appxmanifest b/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.Uwp/Package.appxmanifest deleted file mode 100644 index 4da921f0f..000000000 --- a/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.Uwp/Package.appxmanifest +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - CompositionCollectionView.UnitTests.Uwp - CommunityToolkit - Assets\StoreLogo.png - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.Uwp/Properties/AssemblyInfo.cs b/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.Uwp/Properties/AssemblyInfo.cs deleted file mode 100644 index 3b5781f36..000000000 --- a/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.Uwp/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -[assembly: AssemblyTitle("CompositionCollectionView.UnitTests.Uwp")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany(".NET Foundation")] -[assembly: AssemblyProduct("CompositionCollectionView.UnitTests.Uwp")] -[assembly: AssemblyCopyright("Copyright © .NET Foundation 2022")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] -[assembly: AssemblyMetadata("TargetPlatform","UAP")] - -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] -[assembly: ComVisible(false)] \ No newline at end of file diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.Uwp/Properties/Default.rd.xml b/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.Uwp/Properties/Default.rd.xml deleted file mode 100644 index 996a8392a..000000000 --- a/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.Uwp/Properties/Default.rd.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.WinAppSdk/CompositionCollectionView.UnitTests.WinAppSdk.csproj b/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.WinAppSdk/CompositionCollectionView.UnitTests.WinAppSdk.csproj deleted file mode 100644 index 9f4c1252d..000000000 --- a/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.WinAppSdk/CompositionCollectionView.UnitTests.WinAppSdk.csproj +++ /dev/null @@ -1,33 +0,0 @@ - - - - CompositionCollectionView.UnitTests - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.WinAppSdk/Package.appxmanifest b/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.WinAppSdk/Package.appxmanifest deleted file mode 100644 index 8cb5970dd..000000000 --- a/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.WinAppSdk/Package.appxmanifest +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - CompositionCollectionView.UnitTests.WinAppSdk - CommunityToolkit - Assets\StoreLogo.png - - - - - - - - - - - - - - - - - - - - - - - diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.WinAppSdk/Properties/launchSettings.json b/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.WinAppSdk/Properties/launchSettings.json deleted file mode 100644 index 3aa65aa72..000000000 --- a/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.WinAppSdk/Properties/launchSettings.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "profiles": { - "CompositionCollectionView.UnitTests.WinAppSdk (Package)": { - "commandName": "MsixPackage" - }, - "CompositionCollectionView.UnitTests.WinAppSdk (Unpackaged)": { - "commandName": "Project" - } - } -} diff --git a/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.WinAppSdk/app.manifest b/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.WinAppSdk/app.manifest deleted file mode 100644 index 84b8521ee..000000000 --- a/labs/CompositionCollectionView/tests/CompositionCollectionView.UnitTests.WinAppSdk/app.manifest +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - true/PM - PerMonitorV2, PerMonitor - - - From 9aae744c1b8bfdd010117efbcda3a728dfe8800b Mon Sep 17 00:00:00 2001 From: Arlo Godfrey Date: Fri, 24 Feb 2023 11:39:55 -0600 Subject: [PATCH 36/44] Fixed compilation errors for tests --- ...ampleCompositionCollectionViewTestClass.cs | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/components/CompositionCollectionView/tests/ExampleCompositionCollectionViewTestClass.cs b/components/CompositionCollectionView/tests/ExampleCompositionCollectionViewTestClass.cs index 372f1761c..5ba4b8284 100644 --- a/components/CompositionCollectionView/tests/ExampleCompositionCollectionViewTestClass.cs +++ b/components/CompositionCollectionView/tests/ExampleCompositionCollectionViewTestClass.cs @@ -2,8 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using CommunityToolkit.Labs.Core.SourceGenerators.LabsUITestMethod; -using CommunityToolkit.Labs.Tests; +using CommunityToolkit.Tooling.TestGen; +using CommunityToolkit.Tests; +using CommunityToolkit.Labs.WinUI; namespace CompositionCollectionViewExperiment.Tests; @@ -41,18 +42,18 @@ public void SimpleExceptionCheckTest() Assert.ThrowsException(() => throw new NotImplementedException()); } - // The LabsUITestMethod automatically dispatches to the UI for us to work with UI objects. - [LabsUITestMethod] + // The UIThreadTestMethod automatically dispatches to the UI for us to work with UI objects. + [UIThreadTestMethod] public void SimpleUIAttributeExampleTest() { var component = new CompositionCollectionView(); Assert.IsNotNull(component); } - // The LabsUITestMethod can also easily grab a XAML Page for us by passing its type as a parameter. + // The UIThreadTestMethod can also easily grab a XAML Page for us by passing its type as a parameter. // This lets us actually test a control as it would behave within an actual application. // The page will already be loaded by the time your test is called. - [LabsUITestMethod] + [UIThreadTestMethod] public void SimpleUIExamplePageTest(ExampleCompositionCollectionViewTestPage page) { // You can use the Toolkit Visual Tree helpers here to find the component by type or name: @@ -65,8 +66,8 @@ public void SimpleUIExamplePageTest(ExampleCompositionCollectionViewTestPage pag Assert.IsNotNull(componentByName); } - // You can still do async work with a LabsUITestMethod as well. - [LabsUITestMethod] + // You can still do async work with a UIThreadTestMethod as well. + [UIThreadTestMethod] public async Task SimpleAsyncUIExamplePageTest(ExampleCompositionCollectionViewTestPage page) { // This helper can be used to wait for a rendering pass to complete. @@ -80,7 +81,7 @@ public async Task SimpleAsyncUIExamplePageTest(ExampleCompositionCollectionViewT //// ----------------------------- ADVANCED TEST SCENARIOS ----------------------------- // If you need to use DataRow, you can use this pattern with the UI dispatch still. - // Otherwise, checkout the LabsUITestMethod attribute above. + // Otherwise, checkout the UIThreadTestMethod attribute above. // See https://github.com/CommunityToolkit/Labs-Windows/issues/186 [TestMethod] public async Task ComplexAsyncUIExampleTest() @@ -92,7 +93,7 @@ await EnqueueAsync(() => }); } - // If you want to load other content not within a XAML page using the LabsUITestMethod above. + // If you want to load other content not within a XAML page using the UIThreadTestMethod above. // Then you can do that using the Load/UnloadTestContentAsync methods. [TestMethod] public async Task ComplexAsyncLoadUIExampleTest() @@ -113,8 +114,8 @@ await EnqueueAsync(async () => }); } - // You can still use the LabsUITestMethod to remove the extra layer for the dispatcher as well: - [LabsUITestMethod] + // You can still use the UIThreadTestMethod to remove the extra layer for the dispatcher as well: + [UIThreadTestMethod] public async Task ComplexAsyncLoadUIExampleWithoutDispatcherTest() { var component = new CompositionCollectionView_ClassicBinding(); From c06af8c255f3b805c374bc2ad1812bdfd92d9664 Mon Sep 17 00:00:00 2001 From: Arlo Godfrey Date: Fri, 24 Feb 2023 12:28:38 -0600 Subject: [PATCH 37/44] Fixed compilation errors --- .../tests/ExampleCompositionCollectionViewTestClass.cs | 10 +++++----- .../ExampleCompositionCollectionViewTestPage.xaml | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/components/CompositionCollectionView/tests/ExampleCompositionCollectionViewTestClass.cs b/components/CompositionCollectionView/tests/ExampleCompositionCollectionViewTestClass.cs index 5ba4b8284..e9aad792c 100644 --- a/components/CompositionCollectionView/tests/ExampleCompositionCollectionViewTestClass.cs +++ b/components/CompositionCollectionView/tests/ExampleCompositionCollectionViewTestClass.cs @@ -57,7 +57,7 @@ public void SimpleUIAttributeExampleTest() public void SimpleUIExamplePageTest(ExampleCompositionCollectionViewTestPage page) { // You can use the Toolkit Visual Tree helpers here to find the component by type or name: - var component = page.FindDescendant(); + var component = page.FindDescendant(); Assert.IsNotNull(component); @@ -73,7 +73,7 @@ public async Task SimpleAsyncUIExamplePageTest(ExampleCompositionCollectionViewT // This helper can be used to wait for a rendering pass to complete. await CompositionTargetHelper.ExecuteAfterCompositionRenderingAsync(() => { }); - var component = page.FindDescendant(); + var component = page.FindDescendant(); Assert.IsNotNull(component); } @@ -88,7 +88,7 @@ public async Task ComplexAsyncUIExampleTest() { await EnqueueAsync(() => { - var component = new CompositionCollectionView_ClassicBinding(); + var component = new CompositionCollectionView(); Assert.IsNotNull(component); }); } @@ -100,7 +100,7 @@ public async Task ComplexAsyncLoadUIExampleTest() { await EnqueueAsync(async () => { - var component = new CompositionCollectionView_ClassicBinding(); + var component = new CompositionCollectionView(); Assert.IsNotNull(component); Assert.IsFalse(component.IsLoaded); @@ -118,7 +118,7 @@ await EnqueueAsync(async () => [UIThreadTestMethod] public async Task ComplexAsyncLoadUIExampleWithoutDispatcherTest() { - var component = new CompositionCollectionView_ClassicBinding(); + var component = new CompositionCollectionView(); Assert.IsNotNull(component); Assert.IsFalse(component.IsLoaded); diff --git a/components/CompositionCollectionView/tests/ExampleCompositionCollectionViewTestPage.xaml b/components/CompositionCollectionView/tests/ExampleCompositionCollectionViewTestPage.xaml index 09a72853a..4c642a086 100644 --- a/components/CompositionCollectionView/tests/ExampleCompositionCollectionViewTestPage.xaml +++ b/components/CompositionCollectionView/tests/ExampleCompositionCollectionViewTestPage.xaml @@ -1,4 +1,4 @@ - + - - - + + + From 790fdd0d42f8b6f9e5e8b9ca8638a0384111d876 Mon Sep 17 00:00:00 2001 From: Arcadio Garcia Salvadores Date: Thu, 9 Mar 2023 20:50:46 -0800 Subject: [PATCH 38/44] Remove extra shared project --- .../src/CompositionCollectionView.shproj | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 components/CompositionCollectionView/src/CompositionCollectionView.shproj diff --git a/components/CompositionCollectionView/src/CompositionCollectionView.shproj b/components/CompositionCollectionView/src/CompositionCollectionView.shproj deleted file mode 100644 index a3f494d24..000000000 --- a/components/CompositionCollectionView/src/CompositionCollectionView.shproj +++ /dev/null @@ -1,13 +0,0 @@ - - - - bdb6d5d0-b5e2-4ade-9896-30cd295c2d7a - 14.0 - - - - - - - - From 8bac431fa483a6d4d4d6c4898a3fabe05d9ce0d9 Mon Sep 17 00:00:00 2001 From: Arcadio Garcia Salvadores Date: Thu, 9 Mar 2023 21:26:35 -0800 Subject: [PATCH 39/44] Fix lerp implementation & compile error --- ...olkit.Labs.WinUI.CompositionCollectionView.csproj | 2 +- .../Expressions/ExpressionNodes/Matrix4x4Node.cs | 10 +++++----- .../Expressions/ExpressionNodes/Vector3Node.cs | 12 +++--------- 3 files changed, 9 insertions(+), 15 deletions(-) diff --git a/components/CompositionCollectionView/src/CommunityToolkit.Labs.WinUI.CompositionCollectionView.csproj b/components/CompositionCollectionView/src/CommunityToolkit.Labs.WinUI.CompositionCollectionView.csproj index 4587ca339..7fcbcfbda 100644 --- a/components/CompositionCollectionView/src/CommunityToolkit.Labs.WinUI.CompositionCollectionView.csproj +++ b/components/CompositionCollectionView/src/CommunityToolkit.Labs.WinUI.CompositionCollectionView.csproj @@ -2,7 +2,7 @@ CompositionCollectionView This package contains CompositionCollectionView. - 0.0.25 + 0.0.29 warnings True diff --git a/components/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/Matrix4x4Node.cs b/components/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/Matrix4x4Node.cs index 4d1f6a3e9..191602f27 100644 --- a/components/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/Matrix4x4Node.cs +++ b/components/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/Matrix4x4Node.cs @@ -3,7 +3,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; using System.Numerics; namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork @@ -364,8 +363,8 @@ public Vector4Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, S public Matrix3x2Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4, Subchannel s5, Subchannel s6) { return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString(), s5.ToString(), s6.ToString()); - } - + } + /// /// Create a new type by re-arranging the Matrix subchannels. /// @@ -483,5 +482,6 @@ Matrix4x4 GetProperty() throw new NotImplementedException($"Operation ${NodeType} not implemented for Matrix4x4Node"); } } - } -#pragma warning restore CS0660, CS0661 \ No newline at end of file + } +#pragma warning restore CS0660, CS0661 +} diff --git a/components/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/Vector3Node.cs b/components/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/Vector3Node.cs index 5842c32df..15d464d58 100644 --- a/components/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/Vector3Node.cs +++ b/components/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/Vector3Node.cs @@ -3,7 +3,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; using System.Numerics; namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork @@ -281,8 +280,8 @@ public Vector4Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, S public Matrix3x2Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3, Subchannel s4, Subchannel s5, Subchannel s6) { return SubchannelsInternal(s1.ToString(), s2.ToString(), s3.ToString(), s4.ToString(), s5.ToString(), s6.ToString()); - } - + } + /// /// Create a new type by re-arranging the Vector subchannels. /// @@ -368,12 +367,7 @@ Vector3 GetProperty() (Children[0] as Vector3Node).Evaluate() - (Children[1] as Vector3Node).Evaluate(); case ExpressionNodeType.Lerp: - { - var t = (Children[2] as ScalarNode).Evaluate(); - return - (Children[0] as Vector3Node).Evaluate() * t - - (Children[1] as Vector3Node).Evaluate() * (1 - t); - } + return Vector3.Lerp((Children[0] as Vector3Node).Evaluate(), (Children[1] as Vector3Node).Evaluate(), (Children[2] as ScalarNode).Evaluate()); case ExpressionNodeType.Negate: return -(Children[0] as Vector3Node).Evaluate(); From fdc41d672da25da7009fa7f422de640e7076e81a Mon Sep 17 00:00:00 2001 From: Arlo Godfrey Date: Fri, 10 Mar 2023 18:17:20 -0600 Subject: [PATCH 40/44] Merge fix --- common/GlobalUsings_WinUI.cs | 16 +++++++++++++--- .../Tests.Uwp/CommunityToolkit.Tests.Uwp.csproj | 6 +----- .../Uwp/CommunityToolkit.App.Uwp.csproj | 2 -- .../samples/MazeSample.xaml.cs | 1 + 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/common/GlobalUsings_WinUI.cs b/common/GlobalUsings_WinUI.cs index 66b6b61b7..e0d2fd57a 100644 --- a/common/GlobalUsings_WinUI.cs +++ b/common/GlobalUsings_WinUI.cs @@ -24,9 +24,13 @@ global using Windows.UI.Xaml.Input; global using Windows.UI.Xaml.Markup; global using Windows.UI.Xaml.Media; -global using Windows.UI.Xaml.Media.Animation; global using Windows.UI.Xaml.Navigation; +global using Windows.UI.Composition; +global using Windows.UI.Composition.Interactions; +global using Windows.UI.Xaml.Hosting; +global using Windows.UI; + #else global using Microsoft.UI.Xaml.Automation; @@ -39,8 +43,14 @@ global using Microsoft.UI.Xaml.Input; global using Microsoft.UI.Xaml.Markup; global using Microsoft.UI.Xaml.Media; -global using Microsoft.UI.Xaml.Media.Animation; global using Microsoft.UI.Xaml.Navigation; + +global using Microsoft.UI.Composition; +global using Microsoft.UI.Composition.Interactions; +global using Microsoft.UI.Xaml.Hosting; +global using Microsoft.UI; +global using Windows.UI; + #endif -global using MUXC = Microsoft.UI.Xaml.Controls; +global using MUXC = Microsoft.UI.Xaml.Controls; \ No newline at end of file diff --git a/common/ProjectHeads/AllComponents/Tests.Uwp/CommunityToolkit.Tests.Uwp.csproj b/common/ProjectHeads/AllComponents/Tests.Uwp/CommunityToolkit.Tests.Uwp.csproj index 40b8ea00e..7ae118b1e 100644 --- a/common/ProjectHeads/AllComponents/Tests.Uwp/CommunityToolkit.Tests.Uwp.csproj +++ b/common/ProjectHeads/AllComponents/Tests.Uwp/CommunityToolkit.Tests.Uwp.csproj @@ -1,7 +1,6 @@  - true @@ -24,21 +23,18 @@ - {FD78002E-C4E6-4BF8-9EC3-C06250DFEF34} CommunityToolkit.Tests CommunityToolkit.Tests.Uwp $(VisualStudioVersion) - Designer - - + \ No newline at end of file diff --git a/common/ProjectHeads/AllComponents/Uwp/CommunityToolkit.App.Uwp.csproj b/common/ProjectHeads/AllComponents/Uwp/CommunityToolkit.App.Uwp.csproj index cced3a617..79a071224 100644 --- a/common/ProjectHeads/AllComponents/Uwp/CommunityToolkit.App.Uwp.csproj +++ b/common/ProjectHeads/AllComponents/Uwp/CommunityToolkit.App.Uwp.csproj @@ -1,7 +1,6 @@  - true @@ -24,7 +23,6 @@ - CommunityToolkit.App.Uwp CommunityToolkit.App.Uwp diff --git a/components/CompositionCollectionView/samples/MazeSample.xaml.cs b/components/CompositionCollectionView/samples/MazeSample.xaml.cs index 08aea689b..1a9de5217 100644 --- a/components/CompositionCollectionView/samples/MazeSample.xaml.cs +++ b/components/CompositionCollectionView/samples/MazeSample.xaml.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using CommunityToolkit.Labs.WinUI; using Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork; using System.Numerics; From 9c2a469a00c07db35ae027e5c34533068bd75718 Mon Sep 17 00:00:00 2001 From: Arcadio Garcia Salvadores Date: Sat, 11 Mar 2023 14:01:35 -0800 Subject: [PATCH 41/44] Address feedback --- common/GlobalUsings_WinUI.cs | 2 -- .../src/BindableCompositionPropertySet.cs | 5 +---- .../Expressions/ExpressionNodes/ColorNode.cs | 6 +++--- .../Expressions/ExpressionNodes/ExpressionNode.cs | 3 ++- 4 files changed, 6 insertions(+), 10 deletions(-) diff --git a/common/GlobalUsings_WinUI.cs b/common/GlobalUsings_WinUI.cs index e0d2fd57a..3a82bfa28 100644 --- a/common/GlobalUsings_WinUI.cs +++ b/common/GlobalUsings_WinUI.cs @@ -29,7 +29,6 @@ global using Windows.UI.Composition; global using Windows.UI.Composition.Interactions; global using Windows.UI.Xaml.Hosting; -global using Windows.UI; #else @@ -49,7 +48,6 @@ global using Microsoft.UI.Composition.Interactions; global using Microsoft.UI.Xaml.Hosting; global using Microsoft.UI; -global using Windows.UI; #endif diff --git a/components/CompositionCollectionView/src/BindableCompositionPropertySet.cs b/components/CompositionCollectionView/src/BindableCompositionPropertySet.cs index f82c3dbfb..9a38fba79 100644 --- a/components/CompositionCollectionView/src/BindableCompositionPropertySet.cs +++ b/components/CompositionCollectionView/src/BindableCompositionPropertySet.cs @@ -2,11 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. #nullable enable -using System; -using System.Collections.Generic; -using System.ComponentModel; using System.Numerics; -using System.Text; +using Windows.UI; namespace CommunityToolkit.Labs.WinUI; diff --git a/components/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/ColorNode.cs b/components/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/ColorNode.cs index f1a5f56e2..efe2e7f22 100644 --- a/components/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/ColorNode.cs +++ b/components/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/ColorNode.cs @@ -3,7 +3,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; +using Windows.UI; namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork { @@ -128,8 +128,8 @@ Color GetProperty() (Children[0] as BooleanNode).Evaluate() ? (Children[1] as ColorNode).Evaluate() : (Children[2] as ColorNode).Evaluate(); - default: - throw new NotImplementedException($"Operation ${NodeType} not implemented for ColorNode"); + default: + throw new NotImplementedException($"Operation ${NodeType} not implemented for ColorNode"); } } } diff --git a/components/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/ExpressionNode.cs b/components/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/ExpressionNode.cs index c0ebeaa91..106f995f3 100644 --- a/components/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/ExpressionNode.cs +++ b/components/CompositionCollectionView/src/ExpressionsFork/Expressions/ExpressionNodes/ExpressionNode.cs @@ -2,8 +2,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. - + using System.Numerics; +using Windows.UI; namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork { From 6a0b6c08203f568b5f96c6836dab575615ddd5f8 Mon Sep 17 00:00:00 2001 From: Arcadio Garcia Salvadores Date: Sat, 11 Mar 2023 14:37:10 -0800 Subject: [PATCH 42/44] Fix styling --- .../samples/BasicSample.xaml | 38 +++++++++---------- .../samples/CanvasSample.xaml | 38 +++++++++---------- .../samples/InteractionTrackerSample.xaml | 26 ++++++------- .../samples/MazeSample.xaml | 26 ++++++------- .../samples/SwitchLayoutsSample.xaml | 36 +++++++++--------- .../src/Themes/Generic.xaml | 38 +++++++++---------- ...mpleCompositionCollectionViewTestPage.xaml | 28 +++++++------- 7 files changed, 115 insertions(+), 115 deletions(-) diff --git a/components/CompositionCollectionView/samples/BasicSample.xaml b/components/CompositionCollectionView/samples/BasicSample.xaml index 4a51fb340..e4714e638 100644 --- a/components/CompositionCollectionView/samples/BasicSample.xaml +++ b/components/CompositionCollectionView/samples/BasicSample.xaml @@ -1,19 +1,19 @@ - - - - - - - + + + + + + + diff --git a/components/CompositionCollectionView/samples/CanvasSample.xaml b/components/CompositionCollectionView/samples/CanvasSample.xaml index 515fdf48c..e575a31a6 100644 --- a/components/CompositionCollectionView/samples/CanvasSample.xaml +++ b/components/CompositionCollectionView/samples/CanvasSample.xaml @@ -1,19 +1,19 @@ - - - - - - - + + + + + + + diff --git a/components/CompositionCollectionView/samples/InteractionTrackerSample.xaml b/components/CompositionCollectionView/samples/InteractionTrackerSample.xaml index cd4debbe4..35d63aa33 100644 --- a/components/CompositionCollectionView/samples/InteractionTrackerSample.xaml +++ b/components/CompositionCollectionView/samples/InteractionTrackerSample.xaml @@ -1,13 +1,13 @@ - - - + + + diff --git a/components/CompositionCollectionView/samples/MazeSample.xaml b/components/CompositionCollectionView/samples/MazeSample.xaml index 137787ac9..6320b46b0 100644 --- a/components/CompositionCollectionView/samples/MazeSample.xaml +++ b/components/CompositionCollectionView/samples/MazeSample.xaml @@ -1,13 +1,13 @@ - - - + + + diff --git a/components/CompositionCollectionView/samples/SwitchLayoutsSample.xaml b/components/CompositionCollectionView/samples/SwitchLayoutsSample.xaml index e8787d2a2..7a4d7081b 100644 --- a/components/CompositionCollectionView/samples/SwitchLayoutsSample.xaml +++ b/components/CompositionCollectionView/samples/SwitchLayoutsSample.xaml @@ -1,18 +1,18 @@ - - - - - - - + + + + + + + diff --git a/components/CompositionCollectionView/src/Themes/Generic.xaml b/components/CompositionCollectionView/src/Themes/Generic.xaml index 626bfc26f..e16094aca 100644 --- a/components/CompositionCollectionView/src/Themes/Generic.xaml +++ b/components/CompositionCollectionView/src/Themes/Generic.xaml @@ -1,19 +1,19 @@ - - - - + + + + diff --git a/components/CompositionCollectionView/tests/ExampleCompositionCollectionViewTestPage.xaml b/components/CompositionCollectionView/tests/ExampleCompositionCollectionViewTestPage.xaml index 4c642a086..00f7c3114 100644 --- a/components/CompositionCollectionView/tests/ExampleCompositionCollectionViewTestPage.xaml +++ b/components/CompositionCollectionView/tests/ExampleCompositionCollectionViewTestPage.xaml @@ -1,14 +1,14 @@ - - - - - - - + + + + + + + From 5929330d4f5275ec8a060888464f65922ebe447d Mon Sep 17 00:00:00 2001 From: Arlo Godfrey Date: Mon, 13 Mar 2023 16:56:04 -0500 Subject: [PATCH 43/44] Add missing globalusing --- common/GlobalUsings_WinUI.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/common/GlobalUsings_WinUI.cs b/common/GlobalUsings_WinUI.cs index 3a82bfa28..8af6f322b 100644 --- a/common/GlobalUsings_WinUI.cs +++ b/common/GlobalUsings_WinUI.cs @@ -24,6 +24,7 @@ global using Windows.UI.Xaml.Input; global using Windows.UI.Xaml.Markup; global using Windows.UI.Xaml.Media; +global using Windows.UI.Xaml.Media.Animation; global using Windows.UI.Xaml.Navigation; global using Windows.UI.Composition; @@ -42,6 +43,7 @@ global using Microsoft.UI.Xaml.Input; global using Microsoft.UI.Xaml.Markup; global using Microsoft.UI.Xaml.Media; +global using Microsoft.UI.Xaml.Media.Animation; global using Microsoft.UI.Xaml.Navigation; global using Microsoft.UI.Composition; From 6f978ed92edf9d56e35ecd18eb0035a25da68d07 Mon Sep 17 00:00:00 2001 From: Arlo Date: Mon, 27 May 2024 08:57:25 -0500 Subject: [PATCH 44/44] Update components/CompositionCollectionView/samples/CanvasSample.cs Co-authored-by: Michael Hawker MSFT (XAML Llama) <24302614+michael-hawker@users.noreply.github.com> --- components/CompositionCollectionView/samples/CanvasSample.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/CompositionCollectionView/samples/CanvasSample.cs b/components/CompositionCollectionView/samples/CanvasSample.cs index d1d7f025c..4c48a9451 100644 --- a/components/CompositionCollectionView/samples/CanvasSample.cs +++ b/components/CompositionCollectionView/samples/CanvasSample.cs @@ -31,7 +31,7 @@ namespace CompositionCollectionView.Sample { - [ToolkitSample(id: nameof(CanvasSample), "Canvas layout", description: "DisplayS elements in a 2d canvas, animating between updates.")] + [ToolkitSample(id: nameof(CanvasSample), "Canvas layout", description: "Displays elements in a 2d canvas, animating between updates.")] public sealed partial class CanvasSample : Page { public CanvasSample()