diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
index b135fae1c..564967919 100644
--- a/.config/dotnet-tools.json
+++ b/.config/dotnet-tools.json
@@ -3,13 +3,13 @@
"isRoot": true,
"tools": {
"uno.check": {
- "version": "1.3.1",
+ "version": "1.10.0",
"commands": [
"uno-check"
]
},
"xamlstyler.console": {
- "version": "3.2008.4",
+ "version": "3.2206.4",
"commands": [
"xstyler"
]
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 9a8ffd349..cbfc4c374 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -25,14 +25,14 @@ jobs:
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Needed until XAML Styler updates to .NET 6
- - name: Install .NET Core 3.1 SDK
- uses: actions/setup-dotnet@v1
+ - name: Install .NET 6 SDK
+ uses: actions/setup-dotnet@v3
with:
- dotnet-version: '3.1.x'
+ dotnet-version: '6.0.x'
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- name: Checkout Repository
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
# Restore Tools from Manifest list in the Repository
- name: Restore dotnet tools
@@ -49,13 +49,13 @@ jobs:
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
- name: Install .NET 6 SDK
- uses: actions/setup-dotnet@v1
+ uses: actions/setup-dotnet@v3
with:
- dotnet-version: '6.0.202'
+ dotnet-version: '6.0.x'
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- name: Checkout Repository
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
# Restore Tools from Manifest list in the Repository
- name: Restore dotnet tools
@@ -123,13 +123,13 @@ jobs:
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
- name: Install .NET 6 SDK
- uses: actions/setup-dotnet@v1
+ uses: actions/setup-dotnet@v3
with:
- dotnet-version: '6.0.202'
+ dotnet-version: '6.0.x'
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- name: Checkout Repository
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
# Restore Tools from Manifest list in the Repository
- name: Restore dotnet tools
@@ -200,13 +200,13 @@ jobs:
steps:
- name: Install .NET 6 SDK
- uses: actions/setup-dotnet@v1
+ uses: actions/setup-dotnet@v3
with:
- dotnet-version: '6.0.202'
+ dotnet-version: '6.0.x'
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- name: Checkout Repository
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v1.0.3
@@ -255,13 +255,13 @@ jobs:
steps:
- name: Install .NET 6 SDK
- uses: actions/setup-dotnet@v1
+ uses: actions/setup-dotnet@v3
with:
- dotnet-version: '6.0.201'
+ dotnet-version: '6.0.x'
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- name: Checkout Repository
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
- name: Generate solution
shell: pwsh
diff --git a/common/CommunityToolkit.Labs.Core.SourceGenerators.LabsUITestMethod.Tests/CommunityToolkit.Labs.Core.SourceGenerators.LabsUITestMethod.Tests.csproj b/common/CommunityToolkit.Labs.Core.SourceGenerators.LabsUITestMethod.Tests/CommunityToolkit.Labs.Core.SourceGenerators.LabsUITestMethod.Tests.csproj
index ff9b195ac..891006984 100644
--- a/common/CommunityToolkit.Labs.Core.SourceGenerators.LabsUITestMethod.Tests/CommunityToolkit.Labs.Core.SourceGenerators.LabsUITestMethod.Tests.csproj
+++ b/common/CommunityToolkit.Labs.Core.SourceGenerators.LabsUITestMethod.Tests/CommunityToolkit.Labs.Core.SourceGenerators.LabsUITestMethod.Tests.csproj
@@ -10,8 +10,8 @@
-
-
+
+
diff --git a/common/CommunityToolkit.Labs.Core.SourceGenerators.Tests/CommunityToolkit.Labs.Core.SourceGenerators.Tests/CommunityToolkit.Labs.Core.SourceGenerators.Tests.csproj b/common/CommunityToolkit.Labs.Core.SourceGenerators.Tests/CommunityToolkit.Labs.Core.SourceGenerators.Tests/CommunityToolkit.Labs.Core.SourceGenerators.Tests.csproj
index 4b5907449..2a1967ee9 100644
--- a/common/CommunityToolkit.Labs.Core.SourceGenerators.Tests/CommunityToolkit.Labs.Core.SourceGenerators.Tests/CommunityToolkit.Labs.Core.SourceGenerators.Tests.csproj
+++ b/common/CommunityToolkit.Labs.Core.SourceGenerators.Tests/CommunityToolkit.Labs.Core.SourceGenerators.Tests/CommunityToolkit.Labs.Core.SourceGenerators.Tests.csproj
@@ -10,8 +10,8 @@
-
-
+
+
diff --git a/common/CommunityToolkit.Labs.Tests.Shared/App.xaml.cs b/common/CommunityToolkit.Labs.Tests.Shared/App.xaml.cs
index 1b12ef5c4..001deddb9 100644
--- a/common/CommunityToolkit.Labs.Tests.Shared/App.xaml.cs
+++ b/common/CommunityToolkit.Labs.Tests.Shared/App.xaml.cs
@@ -17,6 +17,7 @@
using Windows.UI.Xaml.Navigation;
#else
using Microsoft.UI.Dispatching;
+using Microsoft.UI.Windowing;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
@@ -25,6 +26,7 @@
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Navigation;
using Microsoft.VisualStudio.TestTools.UnitTesting.AppContainer;
+using System.Runtime.InteropServices;
#endif
namespace CommunityToolkit.Labs.Tests;
@@ -37,16 +39,16 @@ public sealed partial class App : Application
// MacOS and iOS don't know the correct type without a full namespace declaration, confusing it with NSWindow and UIWindow.
// Using static will not work.
#if WINAPPSDK
- private static Microsoft.UI.Xaml.Window currentWindow = Microsoft.UI.Xaml.Window.Current;
+ public static Microsoft.UI.Xaml.Window CurrentWindow = Microsoft.UI.Xaml.Window.Current;
#else
- private static Windows.UI.Xaml.Window currentWindow = Windows.UI.Xaml.Window.Current;
+ public static Windows.UI.Xaml.Window CurrentWindow = Windows.UI.Xaml.Window.Current;
#endif
// Holder for test content to abstract Window.Current.Content
public static FrameworkElement? ContentRoot
{
- get => currentWindow.Content as FrameworkElement;
- set => currentWindow.Content = value;
+ get => CurrentWindow.Content as FrameworkElement;
+ set => CurrentWindow.Content = value;
}
// Abstract CoreApplication.MainView.DispatcherQueue
@@ -57,7 +59,7 @@ public static DispatcherQueue DispatcherQueue
#if !WINAPPSDK
return CoreApplication.MainView.DispatcherQueue;
#else
- return currentWindow.DispatcherQueue;
+ return CurrentWindow.DispatcherQueue;
#endif
}
}
@@ -79,15 +81,15 @@ public App()
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
#if WINAPPSDK
- currentWindow = new Window();
+ CurrentWindow = new Window();
#endif
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
- if (currentWindow.Content is not Frame rootFrame)
+ if (CurrentWindow.Content is not Frame rootFrame)
{
// Create a Frame to act as the navigation context and navigate to the first page
- currentWindow.Content = rootFrame = new Frame();
+ CurrentWindow.Content = rootFrame = new Frame();
rootFrame.NavigationFailed += OnNavigationFailed;
}
@@ -95,7 +97,7 @@ protected override void OnLaunched(LaunchActivatedEventArgs e)
////Microsoft.VisualStudio.TestPlatform.TestExecutor.UnitTestClient.CreateDefaultUI();
// Ensure the current window is active
- currentWindow.Activate();
+ CurrentWindow.Activate();
#if !WINAPPSDK
Microsoft.VisualStudio.TestPlatform.TestExecutor.UnitTestClient.Run(e.Arguments);
diff --git a/common/CommunityToolkit.Labs.Tests.Shared/CommunityToolkit.Labs.Tests.Shared.projitems b/common/CommunityToolkit.Labs.Tests.Shared/CommunityToolkit.Labs.Tests.Shared.projitems
index 9dad91eb3..211be684f 100644
--- a/common/CommunityToolkit.Labs.Tests.Shared/CommunityToolkit.Labs.Tests.Shared.projitems
+++ b/common/CommunityToolkit.Labs.Tests.Shared/CommunityToolkit.Labs.Tests.Shared.projitems
@@ -18,7 +18,14 @@
App.xaml
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/common/CommunityToolkit.Labs.Tests.Shared/Input/InputHelpers.cs b/common/CommunityToolkit.Labs.Tests.Shared/Input/InputHelpers.cs
new file mode 100644
index 000000000..5917fbc47
--- /dev/null
+++ b/common/CommunityToolkit.Labs.Tests.Shared/Input/InputHelpers.cs
@@ -0,0 +1,30 @@
+// 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
+using MainWindow = Microsoft.UI.Xaml.Window;
+#else
+using MainWindow = Windows.UI.Xaml.Window;
+#endif
+
+namespace CommunityToolkit.Labs.Tests;
+
+public static class InputHelpers
+{
+ ///
+ /// Helper extension method to create a new chain for the current window.
+ ///
+ /// class for your application.
+ /// A new instance for that window.
+ public static InputSimulator InjectInput(this MainWindow window)
+ {
+ return new InputSimulator(window);
+ }
+
+ public static Point CoordinatesToCenter(this UIElement parent, UIElement target)
+ {
+ var location = target.TransformToVisual(parent).TransformPoint(default(Point));
+ return new(location.X + target.ActualSize.X / 2, location.Y + target.ActualSize.Y / 2);
+ }
+}
diff --git a/common/CommunityToolkit.Labs.Tests.Shared/Input/InputSimulator.Bounds.cs b/common/CommunityToolkit.Labs.Tests.Shared/Input/InputSimulator.Bounds.cs
new file mode 100644
index 000000000..06bfae09c
--- /dev/null
+++ b/common/CommunityToolkit.Labs.Tests.Shared/Input/InputSimulator.Bounds.cs
@@ -0,0 +1,61 @@
+// 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
+using Windows.Win32;
+using Windows.Win32.Foundation;
+using Win32Rect = Windows.Win32.Foundation.RECT;
+using Win32Point = System.Drawing.Point;
+#endif
+
+namespace CommunityToolkit.Labs.Tests;
+
+//// This polyfill is needed as the WindowsAppSDK doesn't provide client based coordinates. See Issue: TODO: File bug currentWindow.Bounds should be the same between the two platforms. Should AppWindow also have Bounds?
+
+public partial class InputSimulator
+{
+#if WINAPPSDK
+ private Rect Bounds
+ {
+ get
+ {
+ if (_currentWindowRef.TryGetTarget(out var currentWindow))
+ {
+ var hWnd = (HWND)WinRT.Interop.WindowNative.GetWindowHandle(currentWindow);
+
+ // Get client area position
+ Win32Point[] points = new Win32Point[1];
+ PInvoke.MapWindowPoints(hWnd, HWND.Null, points);
+
+ // TODO: Check LastError?
+
+ // And size
+ if (points.Length == 1 && PInvoke.GetClientRect(hWnd, out Win32Rect size))
+ {
+ return new Rect(points[0].X, points[0].Y, size.right - size.left, size.bottom - size.top);
+ }
+ }
+
+ return default;
+ }
+ }
+#else
+ private Rect Bounds => _currentWindowRef.TryGetTarget(out Window window) ? window.Bounds : default;
+#endif
+
+ private Point TranslatePointForWindow(Point point)
+ {
+ // TODO: Do we want a ToPoint extension in the Toolkit? (is there an existing enum we can use to specify which corner/point of the rect? e.g. topleft, center, middleright, etc...?
+
+ // Get the top left screen coordinates of the app window rect.
+ var bounds = Bounds; // Don't double-retrieve the calculated property, TODO: Just make some point helpers (or use ones in Toolkit)
+ Point appBoundsTopLeft = new Point(bounds.Left, bounds.Top);
+
+ // Create the point for input injection and calculate its screen location.
+ return new Point(
+ appBoundsTopLeft.X + point.X,
+ appBoundsTopLeft.Y + point.Y);
+
+ }
+}
diff --git a/common/CommunityToolkit.Labs.Tests.Shared/Input/InputSimulator.Touch.cs b/common/CommunityToolkit.Labs.Tests.Shared/Input/InputSimulator.Touch.cs
new file mode 100644
index 000000000..27c0cf560
--- /dev/null
+++ b/common/CommunityToolkit.Labs.Tests.Shared/Input/InputSimulator.Touch.cs
@@ -0,0 +1,131 @@
+// 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.Input.Preview.Injection;
+
+namespace CommunityToolkit.Labs.Tests;
+
+public partial class InputSimulator
+{
+ public void StartTouch()
+ {
+ Assert.IsNotNull(_input);
+
+ _input.InitializeTouchInjection(
+ InjectedInputVisualizationMode.Default);
+ }
+
+ ///
+ /// Simulates a touch press on screen at the coordinates provided, in app-local coordinates. For instance use App.ContentRoot.CoordinatesTo(element)
.
+ ///
+ ///
+ ///
+ public uint TouchDown(Point point)
+ {
+ // Create a unique pointer ID for the injected touch pointer.
+ // Multiple input pointers would require more robust handling.
+ uint pointerId = _currentPointerId++;
+
+ var injectionPoint = TranslatePointForWindow(point);
+
+ // Create a touch data point for pointer down.
+ // Each element in the touch data list represents a single touch contact.
+ // For this example, we're mirroring a single mouse pointer.
+ List touchData = new()
+ {
+ new()
+ {
+ Contact = new InjectedInputRectangle
+ {
+ Left = 30, Top = 30, Bottom = 30, Right = 30
+ },
+ PointerInfo = new InjectedInputPointerInfo
+ {
+ PointerId = pointerId,
+ PointerOptions =
+ InjectedInputPointerOptions.PointerDown |
+ InjectedInputPointerOptions.InContact |
+ InjectedInputPointerOptions.New,
+ TimeOffsetInMilliseconds = 0,
+ PixelLocation = new InjectedInputPoint
+ {
+ PositionX = (int)injectionPoint.X ,
+ PositionY = (int)injectionPoint.Y
+ }
+ },
+ Pressure = 1.0,
+ TouchParameters =
+ InjectedInputTouchParameters.Pressure |
+ InjectedInputTouchParameters.Contact
+ }
+ };
+
+ // Inject the touch input.
+ _input.InjectTouchInput(touchData);
+
+ return pointerId;
+ }
+
+ public void TouchMove(uint pointerId, int cX, int cY)
+ {
+ // Create a touch data point for pointer up.
+ List touchData = new()
+ {
+ new()
+ {
+ Contact = new InjectedInputRectangle
+ {
+ Left = 30, Top = 30, Bottom = 30, Right = 30
+ },
+ PointerInfo = new InjectedInputPointerInfo
+ {
+ PointerId = pointerId,
+ PointerOptions =
+ InjectedInputPointerOptions.InRange |
+ InjectedInputPointerOptions.InContact,
+ TimeOffsetInMilliseconds = 0,
+ PixelLocation = new InjectedInputPoint
+ {
+ PositionX = (int)cX ,
+ PositionY = (int)cY
+ }
+ },
+ Pressure = 1.0,
+ TouchParameters =
+ InjectedInputTouchParameters.Pressure |
+ InjectedInputTouchParameters.Contact
+ }
+ };
+
+ // Inject the touch input.
+ _input.InjectTouchInput(touchData);
+ }
+
+ public void TouchUp(uint pointerId)
+ {
+ Assert.IsNotNull(_input);
+
+ // Create a touch data point for pointer up.
+ List touchData = new()
+ {
+ new()
+ {
+ PointerInfo = new InjectedInputPointerInfo
+ {
+ PointerId = pointerId,
+ PointerOptions = InjectedInputPointerOptions.PointerUp
+ }
+ }
+ };
+
+ // Inject the touch input.
+ _input.InjectTouchInput(touchData);
+ }
+
+ public void StopTouch()
+ {
+ // Shut down the virtual input device.
+ _input.UninitializeTouchInjection();
+ }
+}
diff --git a/common/CommunityToolkit.Labs.Tests.Shared/Input/InputSimulator.cs b/common/CommunityToolkit.Labs.Tests.Shared/Input/InputSimulator.cs
new file mode 100644
index 000000000..3ee24176a
--- /dev/null
+++ b/common/CommunityToolkit.Labs.Tests.Shared/Input/InputSimulator.cs
@@ -0,0 +1,30 @@
+// 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.Input.Preview.Injection;
+
+#if WINAPPSDK
+using MainWindow = Microsoft.UI.Xaml.Window;
+#else
+using MainWindow = Windows.UI.Xaml.Window;
+#endif
+
+namespace CommunityToolkit.Labs.Tests;
+
+public partial class InputSimulator
+{
+ private static InputInjector _input = InputInjector.TryCreate();
+ private static uint _currentPointerId = 0;
+
+ private WeakReference _currentWindowRef;
+
+ ///
+ /// Create a new helper class for the current window. All positions provided to this API will use the client space of the provided window's top-left as an origin point.
+ ///
+ /// Window to simulate input on, used as a reference for client-space coordinates.
+ public InputSimulator(MainWindow currentWindow)
+ {
+ _currentWindowRef = new(currentWindow);
+ }
+}
diff --git a/common/CommunityToolkit.Labs.Tests.Shared/NativeMethods.txt b/common/CommunityToolkit.Labs.Tests.Shared/NativeMethods.txt
new file mode 100644
index 000000000..cb43ad5ec
--- /dev/null
+++ b/common/CommunityToolkit.Labs.Tests.Shared/NativeMethods.txt
@@ -0,0 +1,2 @@
+GetClientRect
+MapWindowPoints
diff --git a/common/Labs.Head.WinAppSdk.props b/common/Labs.Head.WinAppSdk.props
index ddd2885d1..e6ec2707f 100644
--- a/common/Labs.Head.WinAppSdk.props
+++ b/common/Labs.Head.WinAppSdk.props
@@ -18,8 +18,8 @@
-
-
+
+
diff --git a/common/Labs.MultiTarget.props b/common/Labs.MultiTarget.props
index 841cd5b20..8133f088c 100644
--- a/common/Labs.MultiTarget.props
+++ b/common/Labs.MultiTarget.props
@@ -31,7 +31,7 @@
-
+
diff --git a/global.json b/global.json
index 462e64e31..0983b61c3 100644
--- a/global.json
+++ b/global.json
@@ -1,6 +1,10 @@
{
- "msbuild-sdks":
- {
- "MSBuild.Sdk.Extras":"3.0.23"
- }
-}
\ No newline at end of file
+ "sdk": {
+ "version": "6.0.403",
+ "rollForward": "latestFeature"
+ },
+ "msbuild-sdks":
+ {
+ "MSBuild.Sdk.Extras":"3.0.23"
+ }
+}
diff --git a/labs/SizerBase/src/SizerBase.xaml b/labs/SizerBase/src/SizerBase.xaml
index 58f991fc3..440a35f95 100644
--- a/labs/SizerBase/src/SizerBase.xaml
+++ b/labs/SizerBase/src/SizerBase.xaml
@@ -32,7 +32,11 @@
-