From da838c4fdefc9090db458a5b07dbddab08eeff2c Mon Sep 17 00:00:00 2001 From: Qiutong Shen Date: Wed, 1 Jul 2026 09:40:12 +0800 Subject: [PATCH 1/4] Add PointerTracking scenario to Input sample Migrated from windows-topic-specific-samples (uwp-pointers + uwp-pointers-animation). - Multi-pointer tracking with Canvas visualization - Primary pointer detection with animated Ellipse (Storyboard) - Handles all pointer lifecycle events Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- Samples/Input/cs-winui/Input.csproj | 12 ++ Samples/Input/cs-winui/PointerEllipse.xaml | 54 +++++++ Samples/Input/cs-winui/PointerEllipse.xaml.cs | 52 ++++++ Samples/Input/cs-winui/PointerTracking.xaml | 49 ++++++ .../Input/cs-winui/PointerTracking.xaml.cs | 152 ++++++++++++++++++ Samples/Input/cs-winui/SampleConfiguration.cs | 3 +- Samples/nuget.config | 3 +- 7 files changed, 322 insertions(+), 3 deletions(-) create mode 100644 Samples/Input/cs-winui/PointerEllipse.xaml create mode 100644 Samples/Input/cs-winui/PointerEllipse.xaml.cs create mode 100644 Samples/Input/cs-winui/PointerTracking.xaml create mode 100644 Samples/Input/cs-winui/PointerTracking.xaml.cs diff --git a/Samples/Input/cs-winui/Input.csproj b/Samples/Input/cs-winui/Input.csproj index febae7985..94b2729a0 100644 --- a/Samples/Input/cs-winui/Input.csproj +++ b/Samples/Input/cs-winui/Input.csproj @@ -15,6 +15,8 @@ + + @@ -56,4 +58,14 @@ MSBuild:Compile + + + MSBuild:Compile + + + + + MSBuild:Compile + + diff --git a/Samples/Input/cs-winui/PointerEllipse.xaml b/Samples/Input/cs-winui/PointerEllipse.xaml new file mode 100644 index 000000000..1b1585ddd --- /dev/null +++ b/Samples/Input/cs-winui/PointerEllipse.xaml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + diff --git a/Samples/Input/cs-winui/PointerEllipse.xaml.cs b/Samples/Input/cs-winui/PointerEllipse.xaml.cs new file mode 100644 index 000000000..4e41c1140 --- /dev/null +++ b/Samples/Input/cs-winui/PointerEllipse.xaml.cs @@ -0,0 +1,52 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using Microsoft.UI; +using Microsoft.UI.Xaml.Controls; +using Microsoft.UI.Xaml.Media; + +namespace Input +{ + public sealed partial class PointerEllipse : UserControl + { + private bool primaryEllipse; + + public PointerEllipse() + { + this.InitializeComponent(); + ApplyPointerStyle(false); + } + + public uint PointerId { get; set; } + + public bool PrimaryPointer { get; set; } + + public bool PrimaryEllipse + { + get => primaryEllipse; + set + { + primaryEllipse = value; + ApplyPointerStyle(value); + } + } + + public double Diameter => 120.0; + + private void ApplyPointerStyle(bool isPrimary) + { + if (isPrimary) + { + ellipse.Fill = new SolidColorBrush(Colors.White); + ellipse.Stroke = new SolidColorBrush(Colors.Red); + PrimaryPointerStoryboard.Begin(); + } + else + { + PrimaryPointerStoryboard.Stop(); + ellipse.Fill = new SolidColorBrush(Colors.LightSkyBlue); + ellipse.Stroke = new SolidColorBrush(Colors.DodgerBlue); + } + } + } +} diff --git a/Samples/Input/cs-winui/PointerTracking.xaml b/Samples/Input/cs-winui/PointerTracking.xaml new file mode 100644 index 000000000..a71b81d7f --- /dev/null +++ b/Samples/Input/cs-winui/PointerTracking.xaml @@ -0,0 +1,49 @@ + + + + + + Demonstrates multi-pointer tracking with pointer entered, pressed, moved, released, exited, canceled, and capture lost events. + The primary pointer is highlighted with an animated ellipse while secondary pointers use static feedback. + + + + + + + + + + + + + + + + + + + + + + diff --git a/Samples/Input/cs-winui/PointerTracking.xaml.cs b/Samples/Input/cs-winui/PointerTracking.xaml.cs new file mode 100644 index 000000000..c6383302e --- /dev/null +++ b/Samples/Input/cs-winui/PointerTracking.xaml.cs @@ -0,0 +1,152 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using Microsoft.UI.Input; +using Microsoft.UI.Xaml.Controls; +using Microsoft.UI.Xaml.Input; +using System.Collections.Generic; +using Windows.Foundation; + +namespace Input +{ + public sealed partial class PointerTracking : Page + { + private readonly Dictionary ellipses = new Dictionary(); + private bool primaryExists; + + public PointerTracking() + { + this.InitializeComponent(); + } + + private void OnPointerEntered(object sender, PointerRoutedEventArgs e) + { + if (!e.Pointer.IsInContact) + { + AddPointer(e, "Entered"); + } + + e.Handled = true; + } + + private void OnPointerPressed(object sender, PointerRoutedEventArgs e) + { + pointerCanvas.CapturePointer(e.Pointer); + AddPointer(e, "Pressed"); + e.Handled = true; + } + + private void OnPointerMoved(object sender, PointerRoutedEventArgs e) + { + PointerPoint pointerPoint = e.GetCurrentPoint(pointerCanvas); + if (ellipses.TryGetValue(pointerPoint.PointerId, out PointerEllipse ellipse)) + { + UpdateEllipsePosition(ellipse, pointerPoint.Position); + UpdateLastEvent("Moved", pointerPoint.PointerId); + } + + e.Handled = true; + } + + private void OnPointerReleased(object sender, PointerRoutedEventArgs e) + { + RemovePointer(e, "Released", true); + e.Handled = true; + } + + private void OnPointerExited(object sender, PointerRoutedEventArgs e) + { + if (!e.Pointer.IsInContact) + { + RemovePointer(e, "Exited", true); + } + + e.Handled = true; + } + + private void OnPointerCanceled(object sender, PointerRoutedEventArgs e) + { + RemovePointer(e, "Canceled", true); + e.Handled = true; + } + + private void OnPointerCaptureLost(object sender, PointerRoutedEventArgs e) + { + RemovePointer(e, "CaptureLost", false); + e.Handled = true; + } + + private void AddPointer(PointerRoutedEventArgs e, string eventName) + { + PointerPoint pointerPoint = e.GetCurrentPoint(pointerCanvas); + if (ellipses.TryGetValue(pointerPoint.PointerId, out PointerEllipse existingEllipse)) + { + UpdateEllipsePosition(existingEllipse, pointerPoint.Position); + UpdateLastEvent(eventName, pointerPoint.PointerId); + return; + } + + PointerEllipse pointerEllipse = new PointerEllipse(); + pointerEllipse.PointerId = pointerPoint.PointerId; + + if (pointerPoint.Properties.IsPrimary && !primaryExists) + { + pointerEllipse.PrimaryPointer = true; + pointerEllipse.PrimaryEllipse = true; + primaryExists = true; + PointerPrimary.Text = pointerPoint.PointerId.ToString(); + } + else + { + pointerEllipse.PrimaryPointer = false; + pointerEllipse.PrimaryEllipse = false; + } + + ellipses[pointerPoint.PointerId] = pointerEllipse; + UpdateEllipsePosition(pointerEllipse, pointerPoint.Position); + pointerCanvas.Children.Add(pointerEllipse); + UpdatePointerCount(); + UpdateLastEvent(eventName, pointerPoint.PointerId); + } + + private void RemovePointer(PointerRoutedEventArgs e, string eventName, bool releaseCapture) + { + if (releaseCapture) + { + pointerCanvas.ReleasePointerCapture(e.Pointer); + } + + PointerPoint pointerPoint = e.GetCurrentPoint(pointerCanvas); + if (pointerPoint.Properties.IsPrimary) + { + PointerPrimary.Text = "n/a"; + primaryExists = false; + } + + if (ellipses.TryGetValue(pointerPoint.PointerId, out PointerEllipse ellipse)) + { + pointerCanvas.Children.Remove(ellipse); + ellipses.Remove(pointerPoint.PointerId); + UpdatePointerCount(); + } + + UpdateLastEvent(eventName, pointerPoint.PointerId); + } + + private void UpdateEllipsePosition(PointerEllipse ellipse, Point position) + { + Canvas.SetLeft(ellipse, position.X - (ellipse.Diameter / 2.0)); + Canvas.SetTop(ellipse, position.Y - (ellipse.Diameter / 2.0)); + } + + private void UpdatePointerCount() + { + PointerCounter.Text = ellipses.Count.ToString(); + } + + private void UpdateLastEvent(string eventName, uint pointerId) + { + LastEvent.Text = eventName + " (" + pointerId.ToString() + ")"; + } + } +} diff --git a/Samples/Input/cs-winui/SampleConfiguration.cs b/Samples/Input/cs-winui/SampleConfiguration.cs index 903541f91..755a9fac5 100644 --- a/Samples/Input/cs-winui/SampleConfiguration.cs +++ b/Samples/Input/cs-winui/SampleConfiguration.cs @@ -19,7 +19,8 @@ public partial class MainPage : Page { new Scenario() { Title = "Gesture Recognizer", ClassName = typeof(GestureRecognizer).FullName }, new Scenario() { Title = "Gesture Recognizer Manipulations", ClassName = typeof(GestureRecognizerManipulation).FullName }, - new Scenario() { Title = "Cursor", ClassName = typeof(InputCursor).FullName } + new Scenario() { Title = "Cursor", ClassName = typeof(InputCursor).FullName }, + new Scenario() { Title = "PointerTracking", ClassName = typeof(PointerTracking).FullName } }; } diff --git a/Samples/nuget.config b/Samples/nuget.config index 7da696455..3761aac1c 100644 --- a/Samples/nuget.config +++ b/Samples/nuget.config @@ -9,9 +9,8 @@ - - --> From 1228422a77c3d3a1c2176b6b26d317162226ddd6 Mon Sep 17 00:00:00 2001 From: Qiutong Shen Date: Wed, 1 Jul 2026 13:54:27 +0800 Subject: [PATCH 2/4] Add PointerPointProperties, DeviceCapabilities, and XamlManipulations scenarios - PointerPointProperties: shows pointer info (mouse buttons, pen pressure, touch contact rect) on click/touch with color-coded display - DeviceCapabilities: displays keyboard, mouse, and touch device capabilities - XamlManipulations: demonstrates ManipulationMode with translate, rotate, and inertia controls - Fix Canvas Background='Transparent' for hit-test in PointerPointProperties - Add Landscape.jpg to Content items for GestureRecognizerManipulation scenario - Reorder launchSettings.json to default to Unpackaged profile Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../Input/cs-winui/DeviceCapabilities.xaml | 25 +++ .../Input/cs-winui/DeviceCapabilities.xaml.cs | 35 ++++ Samples/Input/cs-winui/Input.csproj | 19 ++ .../cs-winui/PointerPointProperties.xaml | 29 +++ .../cs-winui/PointerPointProperties.xaml.cs | 194 ++++++++++++++++++ .../cs-winui/Properties/launchSettings.json | 8 +- Samples/Input/cs-winui/SampleConfiguration.cs | 5 +- Samples/Input/cs-winui/XamlManipulations.xaml | 50 +++++ .../Input/cs-winui/XamlManipulations.xaml.cs | 127 ++++++++++++ 9 files changed, 487 insertions(+), 5 deletions(-) create mode 100644 Samples/Input/cs-winui/DeviceCapabilities.xaml create mode 100644 Samples/Input/cs-winui/DeviceCapabilities.xaml.cs create mode 100644 Samples/Input/cs-winui/PointerPointProperties.xaml create mode 100644 Samples/Input/cs-winui/PointerPointProperties.xaml.cs create mode 100644 Samples/Input/cs-winui/XamlManipulations.xaml create mode 100644 Samples/Input/cs-winui/XamlManipulations.xaml.cs diff --git a/Samples/Input/cs-winui/DeviceCapabilities.xaml b/Samples/Input/cs-winui/DeviceCapabilities.xaml new file mode 100644 index 000000000..497ad43d8 --- /dev/null +++ b/Samples/Input/cs-winui/DeviceCapabilities.xaml @@ -0,0 +1,25 @@ + + + + + + + + This scenario demonstrates how to use the KeyboardCapabilities, MouseCapabilities, and TouchCapabilities classes to determine what type of input the current device an app is running on supports. + + + + + + + + + + diff --git a/Samples/Input/cs-winui/DeviceCapabilities.xaml.cs b/Samples/Input/cs-winui/DeviceCapabilities.xaml.cs new file mode 100644 index 000000000..f1c0c2eb9 --- /dev/null +++ b/Samples/Input/cs-winui/DeviceCapabilities.xaml.cs @@ -0,0 +1,35 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System.Text; +using Microsoft.UI.Xaml.Controls; +using Windows.Devices.Input; + +namespace Input +{ + public sealed partial class DeviceCapabilities : Page + { + public DeviceCapabilities() + { + this.InitializeComponent(); + + KeyboardCapabilities kbdCapabilities = new KeyboardCapabilities(); + keyboardText.Text = "Keyboard present = " + kbdCapabilities.KeyboardPresent.ToString(); + + MouseCapabilities mouseCapabilities = new MouseCapabilities(); + StringBuilder sb = new StringBuilder(); + sb.Append("Mouse present = " + mouseCapabilities.MousePresent.ToString() + "\n"); + sb.Append("Number of buttons = " + mouseCapabilities.NumberOfButtons.ToString() + "\n"); + sb.Append("Vertical wheel present = " + mouseCapabilities.VerticalWheelPresent.ToString() + "\n"); + sb.Append("Horizontal wheel present = " + mouseCapabilities.HorizontalWheelPresent.ToString() + "\n"); + sb.Append("Buttons swapped = " + mouseCapabilities.SwapButtons.ToString()); + mouseText.Text = sb.ToString(); + + TouchCapabilities touchCapabilities = new TouchCapabilities(); + sb = new StringBuilder(); + sb.Append("Touch present = " + touchCapabilities.TouchPresent.ToString() + "\n"); + sb.Append("Touch contacts supported = " + touchCapabilities.Contacts.ToString()); + touchText.Text = sb.ToString(); + } + } +} diff --git a/Samples/Input/cs-winui/Input.csproj b/Samples/Input/cs-winui/Input.csproj index 94b2729a0..21d5a2630 100644 --- a/Samples/Input/cs-winui/Input.csproj +++ b/Samples/Input/cs-winui/Input.csproj @@ -12,11 +12,14 @@ Properties\PublishProfiles\win10-$(Platform).pubxml + + + @@ -32,6 +35,7 @@ + @@ -43,6 +47,11 @@ + + + MSBuild:Compile + + MSBuild:Compile @@ -68,4 +77,14 @@ MSBuild:Compile + + + MSBuild:Compile + + + + + MSBuild:Compile + + diff --git a/Samples/Input/cs-winui/PointerPointProperties.xaml b/Samples/Input/cs-winui/PointerPointProperties.xaml new file mode 100644 index 000000000..5175f5afb --- /dev/null +++ b/Samples/Input/cs-winui/PointerPointProperties.xaml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + The PointerPoint class provides basic properties for the input pointer associated with a single mouse, pen/stylus, or touch contact. This scenario demonstrates how to retrieve a PointerPoint object in response to an input event, determine what type of input it is (mouse, pen, or touch), and retrieve properties present for all input types and those specific to its type. + + + + + + + diff --git a/Samples/Input/cs-winui/PointerPointProperties.xaml.cs b/Samples/Input/cs-winui/PointerPointProperties.xaml.cs new file mode 100644 index 000000000..f1d96ae6e --- /dev/null +++ b/Samples/Input/cs-winui/PointerPointProperties.xaml.cs @@ -0,0 +1,194 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System.Collections.Generic; +using System.Text; +using Microsoft.UI; +using Microsoft.UI.Input; +using Microsoft.UI.Xaml.Controls; +using Microsoft.UI.Xaml.Input; +using Microsoft.UI.Xaml.Media; +using WinUIPointerPointProperties = Microsoft.UI.Input.PointerPointProperties; + +namespace Input +{ + public sealed partial class PointerPointProperties : Page + { + private readonly Dictionary popups; + + public PointerPointProperties() + { + this.InitializeComponent(); + + popups = new Dictionary(); + + mainCanvas.PointerPressed += new PointerEventHandler(Pointer_Pressed); + mainCanvas.PointerMoved += new PointerEventHandler(Pointer_Moved); + mainCanvas.PointerReleased += new PointerEventHandler(Pointer_Released); + mainCanvas.PointerExited += new PointerEventHandler(Pointer_Released); + mainCanvas.PointerEntered += new PointerEventHandler(Pointer_Entered); + mainCanvas.PointerWheelChanged += new PointerEventHandler(Pointer_Wheel_Changed); + } + + private void Pointer_Pressed(object sender, PointerRoutedEventArgs e) + { + PointerPoint currentPoint = e.GetCurrentPoint(mainCanvas); + CreateOrUpdatePropertyPopUp(currentPoint); + } + + private void Pointer_Entered(object sender, PointerRoutedEventArgs e) + { + PointerPoint currentPoint = e.GetCurrentPoint(mainCanvas); + if (currentPoint.IsInContact) + { + CreateOrUpdatePropertyPopUp(currentPoint); + } + } + + private void Pointer_Moved(object sender, PointerRoutedEventArgs e) + { + PointerPoint currentPoint = e.GetCurrentPoint(mainCanvas); + if (currentPoint.IsInContact) + { + CreateOrUpdatePropertyPopUp(currentPoint); + } + } + + private void Pointer_Released(object sender, PointerRoutedEventArgs e) + { + PointerPoint currentPoint = e.GetCurrentPoint(mainCanvas); + HidePropertyPopUp(currentPoint); + } + + private void Pointer_Wheel_Changed(object sender, PointerRoutedEventArgs e) + { + PointerPoint currentPoint = e.GetCurrentPoint(mainCanvas); + if (currentPoint.IsInContact) + { + CreateOrUpdatePropertyPopUp(currentPoint); + } + } + + private void CreateOrUpdatePropertyPopUp(PointerPoint currentPoint) + { + string pointerProperties = GetPointerProperties(currentPoint); + string deviceSpecificProperties = GetDeviceSpecificProperties(currentPoint); + RenderPropertyPopUp(pointerProperties, deviceSpecificProperties, currentPoint); + } + + private static string GetPointerProperties(PointerPoint currentPoint) + { + StringBuilder sb = new StringBuilder(); + sb.Append("ID: " + currentPoint.PointerId); + sb.Append("\nX: " + currentPoint.Position.X); + sb.Append("\nY: " + currentPoint.Position.Y); + sb.Append("\nContact: " + currentPoint.IsInContact + "\n"); + return sb.ToString(); + } + + private static string GetDeviceSpecificProperties(PointerPoint currentPoint) + { + string deviceSpecificProperties = string.Empty; + switch (currentPoint.PointerDeviceType) + { + case PointerDeviceType.Mouse: + deviceSpecificProperties = GetMouseProperties(currentPoint); + break; + case PointerDeviceType.Pen: + deviceSpecificProperties = GetPenProperties(currentPoint); + break; + case PointerDeviceType.Touch: + deviceSpecificProperties = GetTouchProperties(currentPoint); + break; + } + + return deviceSpecificProperties; + } + + private static string GetMouseProperties(PointerPoint currentPoint) + { + WinUIPointerPointProperties pointerProperties = currentPoint.Properties; + StringBuilder sb = new StringBuilder(); + sb.Append("Left button: " + pointerProperties.IsLeftButtonPressed); + sb.Append("\nRight button: " + pointerProperties.IsRightButtonPressed); + sb.Append("\nMiddle button: " + pointerProperties.IsMiddleButtonPressed); + sb.Append("\nX1 button: " + pointerProperties.IsXButton1Pressed); + sb.Append("\nX2 button: " + pointerProperties.IsXButton2Pressed); + sb.Append("\nMouse wheel delta: " + pointerProperties.MouseWheelDelta); + return sb.ToString(); + } + + private static string GetTouchProperties(PointerPoint currentPoint) + { + WinUIPointerPointProperties pointerProperties = currentPoint.Properties; + StringBuilder sb = new StringBuilder(); + sb.Append("Contact Rect X: " + pointerProperties.ContactRect.X); + sb.Append("\nContact Rect Y: " + pointerProperties.ContactRect.Y); + sb.Append("\nContact Rect Width: " + pointerProperties.ContactRect.Width); + sb.Append("\nContact Rect Height: " + pointerProperties.ContactRect.Height); + return sb.ToString(); + } + + private static string GetPenProperties(PointerPoint currentPoint) + { + WinUIPointerPointProperties pointerProperties = currentPoint.Properties; + StringBuilder sb = new StringBuilder(); + sb.Append("Barrel button: " + pointerProperties.IsBarrelButtonPressed); + sb.Append("\nEraser: " + pointerProperties.IsEraser); + sb.Append("\nPressure: " + pointerProperties.Pressure); + return sb.ToString(); + } + + private void RenderPropertyPopUp(string pointerProperties, string deviceSpecificProperties, PointerPoint currentPoint) + { + if (popups.ContainsKey(currentPoint.PointerId)) + { + TextBlock pointerText = (TextBlock)popups[currentPoint.PointerId].Children[0]; + pointerText.Text = pointerProperties; + TextBlock deviceSpecificText = (TextBlock)popups[currentPoint.PointerId].Children[1]; + deviceSpecificText.Text = deviceSpecificProperties; + } + else + { + StackPanel pointerPanel = new StackPanel(); + TextBlock pointerText = new TextBlock(); + pointerText.Text = pointerProperties; + pointerPanel.Children.Add(pointerText); + + TextBlock deviceSpecificText = new TextBlock(); + deviceSpecificText.Text = deviceSpecificProperties; + + switch (currentPoint.PointerDeviceType) + { + case PointerDeviceType.Mouse: + deviceSpecificText.Foreground = new SolidColorBrush(Colors.Red); + break; + case PointerDeviceType.Touch: + deviceSpecificText.Foreground = new SolidColorBrush(Colors.Green); + break; + case PointerDeviceType.Pen: + deviceSpecificText.Foreground = new SolidColorBrush(Colors.Yellow); + break; + } + + pointerPanel.Children.Add(deviceSpecificText); + popups[currentPoint.PointerId] = pointerPanel; + mainCanvas.Children.Add(popups[currentPoint.PointerId]); + } + + TranslateTransform transform = new TranslateTransform(); + transform.X = currentPoint.Position.X + 24; + transform.Y = currentPoint.Position.Y + 24; + popups[currentPoint.PointerId].RenderTransform = transform; + } + + private void HidePropertyPopUp(PointerPoint currentPoint) + { + if (popups.ContainsKey(currentPoint.PointerId)) + { + mainCanvas.Children.Remove(popups[currentPoint.PointerId]); + popups.Remove(currentPoint.PointerId); + } + } + } +} diff --git a/Samples/Input/cs-winui/Properties/launchSettings.json b/Samples/Input/cs-winui/Properties/launchSettings.json index 0a4d92d93..52545798a 100644 --- a/Samples/Input/cs-winui/Properties/launchSettings.json +++ b/Samples/Input/cs-winui/Properties/launchSettings.json @@ -1,10 +1,10 @@ -{ +{ "profiles": { - "Input (Package)": { - "commandName": "MsixPackage" - }, "Input (Unpackaged)": { "commandName": "Project" + }, + "Input (Package)": { + "commandName": "MsixPackage" } } } \ No newline at end of file diff --git a/Samples/Input/cs-winui/SampleConfiguration.cs b/Samples/Input/cs-winui/SampleConfiguration.cs index 755a9fac5..5f0ab16b0 100644 --- a/Samples/Input/cs-winui/SampleConfiguration.cs +++ b/Samples/Input/cs-winui/SampleConfiguration.cs @@ -20,7 +20,10 @@ public partial class MainPage : Page new Scenario() { Title = "Gesture Recognizer", ClassName = typeof(GestureRecognizer).FullName }, new Scenario() { Title = "Gesture Recognizer Manipulations", ClassName = typeof(GestureRecognizerManipulation).FullName }, new Scenario() { Title = "Cursor", ClassName = typeof(InputCursor).FullName }, - new Scenario() { Title = "PointerTracking", ClassName = typeof(PointerTracking).FullName } + new Scenario() { Title = "PointerTracking", ClassName = typeof(PointerTracking).FullName }, + new Scenario() { Title = "Pointer Point Properties", ClassName = typeof(PointerPointProperties).FullName }, + new Scenario() { Title = "Device Capabilities", ClassName = typeof(DeviceCapabilities).FullName }, + new Scenario() { Title = "XAML Manipulations", ClassName = typeof(XamlManipulations).FullName } }; } diff --git a/Samples/Input/cs-winui/XamlManipulations.xaml b/Samples/Input/cs-winui/XamlManipulations.xaml new file mode 100644 index 000000000..88fd12cb6 --- /dev/null +++ b/Samples/Input/cs-winui/XamlManipulations.xaml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + This scenario demonstrates how to use the ManipulationMode property to register for specific manipulation events on XAML elements and how to listen for and react to these events, specifically the TranslateX, TranslateY, TranslateInertia, Rotate, and RotateInertia events. Through reacting to these events, the rectangle can be moved and rotated via direct user interaction. + + + + + + + +