From 26be61dc25ebd5f3a2a9d98a6f51971eab36a8f7 Mon Sep 17 00:00:00 2001 From: michael-hawker <24302614+michael-hawker@users.noreply.github.com> Date: Fri, 14 Apr 2023 17:04:50 -0700 Subject: [PATCH 1/4] Fix issue with behavior on Windows App SDK by update tooling to use WASDK 1.3 --- tooling | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tooling b/tooling index 66ab9faeb..8163a9104 160000 --- a/tooling +++ b/tooling @@ -1 +1 @@ -Subproject commit 66ab9faebbcf0118e66008bfa194c1fa2b9b06f0 +Subproject commit 8163a9104948f8a2bcfe99dfff4410d789c4e9d3 From 1e3677966f3c9752e428af6784a91dd49e58039c Mon Sep 17 00:00:00 2001 From: michael-hawker <24302614+michael-hawker@users.noreply.github.com> Date: Fri, 14 Apr 2023 17:44:31 -0700 Subject: [PATCH 2/4] Fixes #388 SizerBase Orientation Property Removes Mouse Extension from XAML Template and does in code-behind as to remove the need to set the Cursor property directly via binding By setting the Cursor DependencyProperty we were losing our detection mechanism, now if it's set it's an explicit override, otherwise we use our logic based on Orientation property Also, switches to new CommunityToolkit.*.Extensions Dependency vs. old copies of Tree helpers Fixes some doc typos Bumps version, tested on UWP, WASDK, and Uno.UI/WASM --- ...mmunityToolkit.Labs.WinUI.SizerBase.csproj | 2 +- .../src/ContentSizer/ContentSizer.Events.cs | 2 +- components/SizerBase/src/Dependencies.props | 26 +- components/SizerBase/src/SizerBase.Events.cs | 2 +- .../SizerBase/src/SizerBase.Properties.cs | 37 +-- components/SizerBase/src/SizerBase.cs | 12 +- components/SizerBase/src/SizerBase.xaml | 3 +- .../src/Toolkit/DependencyObjectExtensions.cs | 225 ------------------ .../FrameworkElementExtensions.Mouse.cs | 113 --------- .../Toolkit/OrientationToObjectConverter.cs | 2 + .../src/Toolkit/TypeToObjectConverter.cs | 91 ------- nuget.config | 10 + tooling | 2 +- 13 files changed, 52 insertions(+), 475 deletions(-) delete mode 100644 components/SizerBase/src/Toolkit/DependencyObjectExtensions.cs delete mode 100644 components/SizerBase/src/Toolkit/FrameworkElementExtensions.Mouse.cs delete mode 100644 components/SizerBase/src/Toolkit/TypeToObjectConverter.cs create mode 100644 nuget.config diff --git a/components/SizerBase/src/CommunityToolkit.Labs.WinUI.SizerBase.csproj b/components/SizerBase/src/CommunityToolkit.Labs.WinUI.SizerBase.csproj index 2c050a007..d80f15f1f 100644 --- a/components/SizerBase/src/CommunityToolkit.Labs.WinUI.SizerBase.csproj +++ b/components/SizerBase/src/CommunityToolkit.Labs.WinUI.SizerBase.csproj @@ -2,7 +2,7 @@ SizerBase This package contains SizerBase. - 0.0.4 + 0.0.5 CommunityToolkit.Labs.WinUI.SizerBaseRns diff --git a/components/SizerBase/src/ContentSizer/ContentSizer.Events.cs b/components/SizerBase/src/ContentSizer/ContentSizer.Events.cs index 3e9b8f567..bf5439f7b 100644 --- a/components/SizerBase/src/ContentSizer/ContentSizer.Events.cs +++ b/components/SizerBase/src/ContentSizer/ContentSizer.Events.cs @@ -2,7 +2,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 CommunityToolkit.Labs.WinUI.SizerBaseLocal; +using CommunityToolkit.WinUI; namespace CommunityToolkit.Labs.WinUI; diff --git a/components/SizerBase/src/Dependencies.props b/components/SizerBase/src/Dependencies.props index e622e1df4..3470b688b 100644 --- a/components/SizerBase/src/Dependencies.props +++ b/components/SizerBase/src/Dependencies.props @@ -9,23 +9,13 @@ For UWP / WinAppSDK / Uno packages, place the package references here. --> - - - - + + + + - - - - - - - - - - - - - - + + + + diff --git a/components/SizerBase/src/SizerBase.Events.cs b/components/SizerBase/src/SizerBase.Events.cs index c3b2c52c0..1161075e8 100644 --- a/components/SizerBase/src/SizerBase.Events.cs +++ b/components/SizerBase/src/SizerBase.Events.cs @@ -72,7 +72,7 @@ protected override void OnManipulationStarting(ManipulationStartingRoutedEventAr /// protected override void OnManipulationDelta(ManipulationDeltaRoutedEventArgs e) { - // We use Trancate here to provide 'snapping' points with the DragIncrement property + // We use Truncate here to provide 'snapping' points with the DragIncrement property // It works for both our negative and positive values, as otherwise we'd need to use // Ceiling when negative and Floor when positive to maintain the correct behavior. var horizontalChange = diff --git a/components/SizerBase/src/SizerBase.Properties.cs b/components/SizerBase/src/SizerBase.Properties.cs index 650e6477a..39b34cb23 100644 --- a/components/SizerBase/src/SizerBase.Properties.cs +++ b/components/SizerBase/src/SizerBase.Properties.cs @@ -2,6 +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. +using CommunityToolkit.WinUI; + #if !WINAPPSDK using CursorEnum = Windows.UI.Core.CoreCursorType; #else @@ -17,7 +19,7 @@ namespace CommunityToolkit.Labs.WinUI; public partial class SizerBase : Control { /// - /// Gets or sets the cursor to use when hovering over the gripper bar. If left as null, the control will manage the cursor automatically based on the property value. + /// Gets or sets the cursor to use when hovering over the gripper bar. If left as null, the control will manage the cursor automatically based on the property value (default). /// public CursorEnum Cursor { @@ -32,13 +34,13 @@ public CursorEnum Cursor DependencyProperty.Register(nameof(Cursor), typeof(CursorEnum), typeof(SizerBase), new PropertyMetadata(null, OnOrientationPropertyChanged)); /// - /// Gets or sets the incremental amount of change for draging with the mouse or touch of a sizer control. Effectively a snapping increment for changes. The default is 1. + /// Gets or sets the incremental amount of change for dragging with the mouse or touch of a sizer control. Effectively a snapping increment for changes. The default is 1. /// /// /// For instance, if the DragIncrement is set to 16. Then when a component is resized with the sizer, it will only increase or decrease in size in that increment. I.e. -16, 0, 16, 32, 48, etc... /// /// - /// This value is indepedent of the property. If you need to provide consistent snapping when moving regardless of input device, set these properties to the same value. + /// This value is independent of the property. If you need to provide consistent snapping when moving regardless of input device, set these properties to the same value. /// public double DragIncrement { @@ -92,35 +94,38 @@ private static void OnOrientationPropertyChanged(DependencyObject d, DependencyP { if (d is SizerBase gripper) { - CursorEnum cursorToUse = gripper.Orientation == Orientation.Vertical ? CursorEnum.SizeWestEast : CursorEnum.SizeNorthSouth; + CursorEnum cursorByOrientation = gripper.Orientation == Orientation.Vertical ? CursorEnum.SizeWestEast : CursorEnum.SizeNorthSouth; // See if there's been a cursor override, otherwise we'll pick var cursor = gripper.ReadLocalValue(CursorProperty); if (cursor == DependencyProperty.UnsetValue || cursor == null) { - cursor = cursorToUse; - - // On UWP, we use the extension in XAML to control this behavior, - // so we'll update it here (and maintain binding). - // We'll keep it in-sync to maintain behavior for WinUI 3 as well. - gripper.SetValue(CursorProperty, cursor); + cursor = cursorByOrientation; + } - // We return here, as the Cursor will trigger this function again anyway to set for WinUI 3 - return; +#if !WINAPPSDK + // On UWP, we use our XAML extension to control this behavior, + // so we'll update it here (and maintain any cursor override). + if (cursor is CursorEnum cursorValue) + { + FrameworkElementExtensions.SetCursor(gripper, cursorValue); } + return; +#endif + // TODO: [UNO] Only supported on certain platforms // See ProtectedCursor here: https://github.com/unoplatform/uno/blob/3fe3862b270b99dbec4d830b547942af61b1a1d9/src/Uno.UI/UI/Xaml/UIElement.cs#L1015-L1023 #if WINAPPSDK && !HAS_UNO // Need to wait until we're at least applying template step of loading before setting Cursor // See https://github.com/microsoft/microsoft-ui-xaml/issues/7062 - if (gripper._applyingTemplate && - cursor is CursorEnum cursorToSet && + if (gripper._appliedTemplate && + cursor is CursorEnum cursorValue && (gripper.ProtectedCursor == null || (gripper.ProtectedCursor is InputSystemCursor current && - current.CursorShape != cursorToSet))) + current.CursorShape != cursorValue))) { - gripper.ProtectedCursor = InputSystemCursor.Create(cursorToSet); + gripper.ProtectedCursor = InputSystemCursor.Create(cursorValue); } #endif } diff --git a/components/SizerBase/src/SizerBase.cs b/components/SizerBase/src/SizerBase.cs index 10a5ea6b8..a138dcfc9 100644 --- a/components/SizerBase/src/SizerBase.cs +++ b/components/SizerBase/src/SizerBase.cs @@ -21,7 +21,7 @@ protected virtual void OnLoaded(RoutedEventArgs e) /// /// Called when the control starts to be dragged by the user. - /// Implementor should record current state of manipulated target at this point in time. + /// Implementer should record current state of manipulated target at this point in time. /// They will receive the cumulative change in or /// based on the property. /// @@ -42,7 +42,7 @@ protected virtual void OnLoaded(RoutedEventArgs e) /// manipulation. This method will be used regardless of input device. It will already /// be adjusted for RightToLeft of the containing /// layout/settings. It will also already account for any settings such as - /// or . The implementor + /// or . The implementer /// just needs to use the provided value to manipulate their baseline stored /// in to provide the desired change. /// @@ -57,7 +57,7 @@ protected virtual void OnLoaded(RoutedEventArgs e) /// The value provided here is the cumulative change from the beginning of the /// manipulation. This method will be used regardless of input device. It will also /// already account for any settings such as or - /// . The implementor just needs + /// . The implementer just needs /// to use the provided value to manipulate their baseline stored /// in to provide the desired change. /// @@ -83,7 +83,7 @@ protected override AutomationPeer OnCreateAutomationPeer() // On Uno the ProtectedCursor isn't supported yet, so we don't need this value. #if WINAPPSDK && !HAS_UNO // Used to track when we're in the OnApplyTemplateStep to change ProtectedCursor value. - private bool _applyingTemplate = false; + private bool _appliedTemplate = false; #endif /// @@ -115,9 +115,9 @@ protected override void OnApplyTemplate() SizerBase_IsEnabledChanged(this, null!); #if WINAPPSDK && !HAS_UNO // On WinAppSDK, we'll trigger this to setup the initial ProtectedCursor value. - _applyingTemplate = true; + _appliedTemplate = true; #endif - // On UWP, we'll check the current Orientation and set the Cursor property to use here still. + // Ensure we have the proper cursor value setup, as we can only set now for WinUI 3 OnOrientationPropertyChanged(this, null!); } diff --git a/components/SizerBase/src/SizerBase.xaml b/components/SizerBase/src/SizerBase.xaml index 58f991fc3..59a468eb0 100644 --- a/components/SizerBase/src/SizerBase.xaml +++ b/components/SizerBase/src/SizerBase.xaml @@ -1,4 +1,4 @@ - + diff --git a/components/SizerBase/src/Toolkit/DependencyObjectExtensions.cs b/components/SizerBase/src/Toolkit/DependencyObjectExtensions.cs deleted file mode 100644 index c28bd5d96..000000000 --- a/components/SizerBase/src/Toolkit/DependencyObjectExtensions.cs +++ /dev/null @@ -1,225 +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. - -// We want this to be private/local to our component. -namespace CommunityToolkit.Labs.WinUI.SizerBaseLocal; - -//// IMPORTANT NOTE: This is the old 6.1.1 version of the extensions as I had issues with TPredicate with the new ones here for some reason and just wanted to get this working for now. - -/// -/// Defines a collection of extensions methods for UI. -/// -public static class VisualTree -{ - /// - /// Find descendant control using its name. - /// - /// Parent element. - /// Name of the control to find - /// Descendant control or null if not found. - public static FrameworkElement? FindDescendantByName(this DependencyObject element, string name) - { - if (element == null || string.IsNullOrWhiteSpace(name)) - { - return null; - } - - if (name.Equals((element as FrameworkElement)?.Name, StringComparison.OrdinalIgnoreCase)) - { - return element as FrameworkElement; - } - - var childCount = VisualTreeHelper.GetChildrenCount(element); - for (int i = 0; i < childCount; i++) - { - var result = VisualTreeHelper.GetChild(element, i).FindDescendantByName(name); - if (result != null) - { - return result; - } - } - - return null; - } - - /// - /// Find first descendant control of a specified type. - /// - /// Type to search for. - /// Parent element. - /// Descendant control or null if not found. - public static T? FindDescendant(this DependencyObject element) - where T : DependencyObject - { - T? retValue = default(T); - var childrenCount = VisualTreeHelper.GetChildrenCount(element); - - for (var i = 0; i < childrenCount; i++) - { - var child = VisualTreeHelper.GetChild(element, i); - if (child is T type) - { - retValue = type; - break; - } - - retValue = FindDescendant(child); - - if (retValue != null) - { - break; - } - } - - return retValue; - } - - /// - /// Find first descendant control of a specified type. - /// - /// Parent element. - /// Type of descendant. - /// Descendant control or null if not found. - public static object? FindDescendant(this DependencyObject element, Type type) - { - object? retValue = null; - var childrenCount = VisualTreeHelper.GetChildrenCount(element); - - for (var i = 0; i < childrenCount; i++) - { - var child = VisualTreeHelper.GetChild(element, i); - if (child.GetType() == type) - { - retValue = child; - break; - } - - retValue = FindDescendant(child, type); - - if (retValue != null) - { - break; - } - } - - return retValue; - } - - /// - /// Find all descendant controls of the specified type. - /// - /// Type to search for. - /// Parent element. - /// Descendant controls or empty if not found. - public static IEnumerable FindDescendants(this DependencyObject element) - where T : DependencyObject - { - var childrenCount = VisualTreeHelper.GetChildrenCount(element); - - for (var i = 0; i < childrenCount; i++) - { - var child = VisualTreeHelper.GetChild(element, i); - if (child is T type) - { - yield return type; - } - - foreach (T childofChild in child.FindDescendants()) - { - yield return childofChild; - } - } - } - - /// - /// Find visual ascendant control using its name. - /// - /// Parent element. - /// Name of the control to find - /// Descendant control or null if not found. - public static FrameworkElement? FindAscendantByName(this DependencyObject element, string name) - { - if (element == null || string.IsNullOrWhiteSpace(name)) - { - return null; - } - - var parent = VisualTreeHelper.GetParent(element); - - if (parent == null) - { - return null; - } - - if (name.Equals((parent as FrameworkElement)?.Name, StringComparison.OrdinalIgnoreCase)) - { - return parent as FrameworkElement; - } - - return parent.FindAscendantByName(name); - } - - /// - /// Find first visual ascendant control of a specified type. - /// - /// Type to search for. - /// Child element. - /// Ascendant control or null if not found. - public static T? FindAscendant(this DependencyObject element) - where T : DependencyObject - { - var parent = VisualTreeHelper.GetParent(element); - - if (parent == null) - { - return default(T); - } - - if (parent is T rtn) - { - return rtn; - } - - return parent.FindAscendant(); - } - - /// - /// Find first visual ascendant control of a specified type. - /// - /// Child element. - /// Type of ascendant to look for. - /// Ascendant control or null if not found. - public static object? FindAscendant(this DependencyObject element, Type type) - { - var parent = VisualTreeHelper.GetParent(element); - - if (parent == null) - { - return null; - } - - if (parent.GetType() == type) - { - return parent; - } - - return parent.FindAscendant(type); - } - - /// - /// Find all visual ascendants for the element. - /// - /// Child element. - /// A collection of parent elements or null if none found. - public static IEnumerable FindAscendants(this DependencyObject element) - { - var parent = VisualTreeHelper.GetParent(element); - - while (parent != null) - { - yield return parent; - parent = VisualTreeHelper.GetParent(parent); - } - } -} diff --git a/components/SizerBase/src/Toolkit/FrameworkElementExtensions.Mouse.cs b/components/SizerBase/src/Toolkit/FrameworkElementExtensions.Mouse.cs deleted file mode 100644 index ab66bdc43..000000000 --- a/components/SizerBase/src/Toolkit/FrameworkElementExtensions.Mouse.cs +++ /dev/null @@ -1,113 +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.Core; - -namespace CommunityToolkit.Labs.WinUI.SizerBaseLocal; - -/// -public static partial class FrameworkElementExtensions -{ - private static readonly object _cursorLock = new object(); - private static readonly CoreCursor _defaultCursor = new CoreCursor(CoreCursorType.Arrow, 1); - private static readonly Dictionary _cursors = - new Dictionary { { CoreCursorType.Arrow, _defaultCursor } }; - - /// - /// Dependency property for specifying the target to be shown - /// over the target . - /// - public static readonly DependencyProperty CursorProperty = - DependencyProperty.RegisterAttached("Cursor", typeof(CoreCursorType), typeof(FrameworkElementExtensions), new PropertyMetadata(CoreCursorType.Arrow, CursorChanged)); - - /// - /// Set the target . - /// - /// Object where the selector cursor type should be shown. - /// Target cursor type value. - public static void SetCursor(FrameworkElement element, CoreCursorType value) - { - element.SetValue(CursorProperty, value); - } - - /// - /// Get the current . - /// - /// Object where the selector cursor type should be shown. - /// Cursor type set on target element. - public static CoreCursorType GetCursor(FrameworkElement element) - { - return (CoreCursorType)element.GetValue(CursorProperty); - } - - private static void CursorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - // TODO: How do we want to indicate this isn't supported on the WinAppSDK? -#if !WINAPPSDK - var element = d as FrameworkElement; - if (element == null) - { - throw new NullReferenceException(nameof(element)); - } - - var value = (CoreCursorType)e.NewValue; - - // lock ensures CoreCursor creation and event handlers attachment/detachment is atomic - lock (_cursorLock) - { - if (!_cursors.ContainsKey(value)) - { - _cursors[value] = new CoreCursor(value, 1); - } - - // make sure event handlers are not attached twice to element - element.PointerEntered -= Element_PointerEntered; - element.PointerEntered += Element_PointerEntered; - element.PointerExited -= Element_PointerExited; - element.PointerExited += Element_PointerExited; - element.Unloaded -= ElementOnUnloaded; - element.Unloaded += ElementOnUnloaded; - } -#endif - } - -#if !WINAPPSDK - private static void Element_PointerEntered(object sender, PointerRoutedEventArgs e) - { - // TODO: [UNO] Only supported on certain platforms - // See PointerCursor here: https://github.com/unoplatform/uno/blob/3fe3862b270b99dbec4d830b547942af61b1a1d9/src/Uno.UWP/UI/Core/CoreWindow.cs#L71-L77 -#if NETFX_CORE || WASM || __MACOS__ || __SKIA__ - CoreCursorType cursor = GetCursor((FrameworkElement)sender); - Window.Current.CoreWindow.PointerCursor = _cursors[cursor]; -#endif - } - - private static void Element_PointerExited(object sender, PointerRoutedEventArgs e) - { -#if NETFX_CORE || WASM || __MACOS__ || __SKIA__ - // when exiting change the cursor to the target Mouse.Cursor value of the new element - CoreCursor cursor; - if (sender != e.OriginalSource && e.OriginalSource is FrameworkElement newElement) - { - cursor = _cursors[GetCursor(newElement)]; - } - else - { - cursor = _defaultCursor; - } - - Window.Current.CoreWindow.PointerCursor = cursor; -#endif - } - - private static void ElementOnUnloaded(object sender, RoutedEventArgs routedEventArgs) - { -#if NETFX_CORE || __WASM__ || __MACOS__ || __SKIA__ - // when the element is programatically unloaded, reset the cursor back to default - // this is necessary when click triggers immediate change in layout and PointerExited is not called - Window.Current.CoreWindow.PointerCursor = _defaultCursor; -#endif - } -#endif -} diff --git a/components/SizerBase/src/Toolkit/OrientationToObjectConverter.cs b/components/SizerBase/src/Toolkit/OrientationToObjectConverter.cs index 358d7c21a..085e974ec 100644 --- a/components/SizerBase/src/Toolkit/OrientationToObjectConverter.cs +++ b/components/SizerBase/src/Toolkit/OrientationToObjectConverter.cs @@ -4,6 +4,8 @@ namespace CommunityToolkit.Labs.WinUI.SizerBaseLocal; +//// TODO: Make this part of the WCT converters package? + /// /// This class returns a value depending on the of the value provided to the converter. In case of default will return the . /// diff --git a/components/SizerBase/src/Toolkit/TypeToObjectConverter.cs b/components/SizerBase/src/Toolkit/TypeToObjectConverter.cs deleted file mode 100644 index 7f1322076..000000000 --- a/components/SizerBase/src/Toolkit/TypeToObjectConverter.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. - -namespace CommunityToolkit.Labs.WinUI.SizerBaseLocal; - -/// -/// This class returns an object or another, depending on whether the type of the provided value matches another provided Type. -/// -[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1001:Types that own disposable fields should be disposable", Justification = "Internal Uno Generator Issue: https://github.com/unoplatform/uno/pull/8743")] -public partial class TypeToObjectConverter : DependencyObject, IValueConverter -{ - /// - /// Identifies the property. - /// - public static readonly DependencyProperty TrueValueProperty = - DependencyProperty.Register(nameof(TrueValue), typeof(object), typeof(TypeToObjectConverter), new PropertyMetadata(null)); - - /// - /// Identifies the property. - /// - public static readonly DependencyProperty FalseValueProperty = - DependencyProperty.Register(nameof(FalseValue), typeof(object), typeof(TypeToObjectConverter), new PropertyMetadata(null)); - - /// - /// Identifies the property. - /// - public static readonly DependencyProperty TypeProperty = - DependencyProperty.Register(nameof(Type), typeof(Type), typeof(TypeToObjectConverter), new PropertyMetadata(typeof(object))); - - /// - /// Gets or sets the value to be returned when the type of the provided value matches . - /// - public object TrueValue - { - get { return GetValue(TrueValueProperty); } - set { SetValue(TrueValueProperty, value); } - } - - /// - /// Gets or sets the value to be returned when the type of the provided value does not match . - /// - public object FalseValue - { - get { return GetValue(FalseValueProperty); } - set { SetValue(FalseValueProperty, value); } - } - - /// - /// Gets or sets the Type used to compare the type of the provided value. - /// - public Type Type - { - get { return (Type)GetValue(TypeProperty); } - set { SetValue(TypeProperty, value); } - } - - /// - /// Convert the 's Type to an other object. - /// - /// The source data being passed to the target. - /// The type of the target property, as a type reference. - /// An optional parameter to be used to invert the converter logic. - /// The language of the conversion. - /// The value to be passed to the target dependency property. - public object Convert(object value, Type targetType, object parameter, string language) - { - var typeMatches = value != null && Type.Equals(value.GetType()); - - // Negate if needed - if (ConverterTools.TryParseBool(parameter)) - { - typeMatches = !typeMatches; - } - - return ConverterTools.Convert(typeMatches ? TrueValue : FalseValue, targetType); - } - - /// - /// Not implemented. - /// - /// The source data being passed to the target. - /// The type of the target property, as a type reference. - /// Optional parameter. Not used. - /// The language of the conversion. Not used. - /// The value to be passed to the target dependency property. - public object ConvertBack(object value, Type targetType, object parameter, string language) - { - throw new NotImplementedException(); - } -} diff --git a/nuget.config b/nuget.config new file mode 100644 index 000000000..c3f797ff6 --- /dev/null +++ b/nuget.config @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/tooling b/tooling index 8163a9104..db8bc0da1 160000 --- a/tooling +++ b/tooling @@ -1 +1 @@ -Subproject commit 8163a9104948f8a2bcfe99dfff4410d789c4e9d3 +Subproject commit db8bc0da1a76538ee6d01a04f63147ad0a9ff459 From 1416e393e08c587acc2fe0b3681e6853884fee68 Mon Sep 17 00:00:00 2001 From: michael-hawker <24302614+michael-hawker@users.noreply.github.com> Date: Sat, 15 Apr 2023 22:10:16 -0700 Subject: [PATCH 3/4] Update other experiments to use new unified package --- components/CanvasView/src/Dependencies.props | 26 ++++++------------- .../SegmentedControl/src/Dependencies.props | 26 ++++++------------- .../SettingsControls/src/Dependencies.props | 24 +++++------------ 3 files changed, 23 insertions(+), 53 deletions(-) diff --git a/components/CanvasView/src/Dependencies.props b/components/CanvasView/src/Dependencies.props index ee01b275e..3470b688b 100644 --- a/components/CanvasView/src/Dependencies.props +++ b/components/CanvasView/src/Dependencies.props @@ -9,23 +9,13 @@ For UWP / WinAppSDK / Uno packages, place the package references here. --> - - - - + + + + - - - - - - - - - - - - - - + + + + diff --git a/components/SegmentedControl/src/Dependencies.props b/components/SegmentedControl/src/Dependencies.props index ee01b275e..3470b688b 100644 --- a/components/SegmentedControl/src/Dependencies.props +++ b/components/SegmentedControl/src/Dependencies.props @@ -9,23 +9,13 @@ For UWP / WinAppSDK / Uno packages, place the package references here. --> - - - - + + + + - - - - - - - - - - - - - - + + + + diff --git a/components/SettingsControls/src/Dependencies.props b/components/SettingsControls/src/Dependencies.props index cff9d9612..3470b688b 100644 --- a/components/SettingsControls/src/Dependencies.props +++ b/components/SettingsControls/src/Dependencies.props @@ -9,23 +9,13 @@ For UWP / WinAppSDK / Uno packages, place the package references here. --> - - - - - - - - - + + + + - - - - - - - - + + + From e824a384ccbb0564aa61740efb6509c54b7fbb62 Mon Sep 17 00:00:00 2001 From: Niels Laute Date: Mon, 17 Apr 2023 20:55:31 +0200 Subject: [PATCH 4/4] [Sizer] Adding modern styles (#2) * Adding modern style * Address feedback * Fixing wrong state names --- components/SizerBase/src/SizerBase.Events.cs | 16 +-- .../SizerBase/src/SizerBase.Properties.cs | 25 ++++ components/SizerBase/src/SizerBase.cs | 23 ++++ components/SizerBase/src/SizerBase.xaml | 120 ++++++++++++------ 4 files changed, 136 insertions(+), 48 deletions(-) diff --git a/components/SizerBase/src/SizerBase.Events.cs b/components/SizerBase/src/SizerBase.Events.cs index 1161075e8..3a87f62e2 100644 --- a/components/SizerBase/src/SizerBase.Events.cs +++ b/components/SizerBase/src/SizerBase.Events.cs @@ -117,7 +117,7 @@ private void SizerBase_PointerReleased(object sender, PointerRoutedEventArgs e) if (IsEnabled) { - VisualStateManager.GoToState(this, _pointerEntered ? "PointerOver" : "Normal", true); + VisualStateManager.GoToState(this, _pointerEntered ? PointerOverState : NormalState, true); } } @@ -127,7 +127,7 @@ private void SizerBase_PointerPressed(object sender, PointerRoutedEventArgs e) if (IsEnabled) { - VisualStateManager.GoToState(this, "Pressed", true); + VisualStateManager.GoToState(this, PointerOverState, true); } } @@ -137,7 +137,7 @@ private void SizerBase_PointerExited(object sender, PointerRoutedEventArgs e) if (!_pressed && !_dragging && IsEnabled) { - VisualStateManager.GoToState(this, "Normal", true); + VisualStateManager.GoToState(this, NormalState, true); } } @@ -147,7 +147,7 @@ private void SizerBase_PointerEntered(object sender, PointerRoutedEventArgs e) if (!_pressed && !_dragging && IsEnabled) { - VisualStateManager.GoToState(this, "PointerOver", true); + VisualStateManager.GoToState(this, PointerOverState, true); } } @@ -155,24 +155,24 @@ private void SizerBase_ManipulationCompleted(object sender, ManipulationComplete { _dragging = false; _pressed = false; - VisualStateManager.GoToState(this, _pointerEntered ? "PointerOver" : "Normal", true); + VisualStateManager.GoToState(this, _pointerEntered ? PointerOverState : NormalState, true); } private void SizerBase_ManipulationStarted(object sender, ManipulationStartedRoutedEventArgs e) { _dragging = true; - VisualStateManager.GoToState(this, "Pressed", true); + VisualStateManager.GoToState(this, PressedState, true); } private void SizerBase_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e) { if (!IsEnabled) { - VisualStateManager.GoToState(this, "Disabled", true); + VisualStateManager.GoToState(this, DisabledState, true); } else { - VisualStateManager.GoToState(this, _pointerEntered ? "PointerOver" : "Normal", true); + VisualStateManager.GoToState(this, _pointerEntered ? PointerOverState : NormalState, true); } } } diff --git a/components/SizerBase/src/SizerBase.Properties.cs b/components/SizerBase/src/SizerBase.Properties.cs index 39b34cb23..dec692218 100644 --- a/components/SizerBase/src/SizerBase.Properties.cs +++ b/components/SizerBase/src/SizerBase.Properties.cs @@ -90,10 +90,28 @@ public Orientation Orientation public static readonly DependencyProperty OrientationProperty = DependencyProperty.Register(nameof(Orientation), typeof(Orientation), typeof(SizerBase), new PropertyMetadata(Orientation.Vertical, OnOrientationPropertyChanged)); + /// + /// Gets or sets if the Thumb is visible. If not visible, only the background and cursor will be shown on MouseOver or Pressed states. + /// + public bool IsThumbVisible + { + get { return (bool)GetValue(IsThumbVisibleProperty); } + set { SetValue(IsThumbVisibleProperty, value); } + } + + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty IsThumbVisibleProperty = + DependencyProperty.Register(nameof(IsThumbVisible), typeof(bool), typeof(SizerBase), new PropertyMetadata(true, OnIsThumbVisiblePropertyChanged)); + + private static void OnOrientationPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is SizerBase gripper) { + VisualStateManager.GoToState(gripper, gripper.Orientation == Orientation.Vertical ? VerticalState : HorizontalState, true); + CursorEnum cursorByOrientation = gripper.Orientation == Orientation.Vertical ? CursorEnum.SizeWestEast : CursorEnum.SizeNorthSouth; // See if there's been a cursor override, otherwise we'll pick @@ -130,4 +148,11 @@ cursor is CursorEnum cursorValue && #endif } } + private static void OnIsThumbVisiblePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + if (d is SizerBase gripper) + { + VisualStateManager.GoToState(gripper, gripper.IsThumbVisible ? VisibleState : CollapsedState, true); + } + } } diff --git a/components/SizerBase/src/SizerBase.cs b/components/SizerBase/src/SizerBase.cs index a138dcfc9..391f0dfc9 100644 --- a/components/SizerBase/src/SizerBase.cs +++ b/components/SizerBase/src/SizerBase.cs @@ -9,8 +9,28 @@ namespace CommunityToolkit.Labs.WinUI; /// /// Base class for splitting/resizing type controls like and . Acts similar to an enlarged type control, but with keyboard support. Subclasses should override the various abstract methods here to implement their behavior. /// + +[TemplateVisualState(Name = NormalState, GroupName = CommonStates)] +[TemplateVisualState(Name = PointerOverState, GroupName = CommonStates)] +[TemplateVisualState(Name = PressedState, GroupName = CommonStates)] +[TemplateVisualState(Name = DisabledState, GroupName = CommonStates)] +[TemplateVisualState(Name = HorizontalState, GroupName = OrientationStates)] +[TemplateVisualState(Name = VerticalState, GroupName = OrientationStates)] +[TemplateVisualState(Name = VisibleState, GroupName = ThumbVisibilityStates)] +[TemplateVisualState(Name = CollapsedState, GroupName = ThumbVisibilityStates)] public abstract partial class SizerBase : Control { + internal const string CommonStates = "CommonStates"; + internal const string NormalState = "Normal"; + internal const string PointerOverState = "PointerOver"; + internal const string PressedState = "Pressed"; + internal const string DisabledState = "Disabled"; + internal const string OrientationStates = "OrientationStates"; + internal const string HorizontalState = "Horizontal"; + internal const string VerticalState = "Vertical"; + internal const string ThumbVisibilityStates = "ThumbVisibilityStates"; + internal const string VisibleState = "Visible"; + internal const string CollapsedState = "Collapsed"; /// /// Called when the control has been initialized. /// @@ -119,6 +139,9 @@ protected override void OnApplyTemplate() #endif // Ensure we have the proper cursor value setup, as we can only set now for WinUI 3 OnOrientationPropertyChanged(this, null!); + + // Ensure we set the Thumb visiblity + OnIsThumbVisiblePropertyChanged(this, null!); } private void SizerBase_Loaded(object sender, RoutedEventArgs e) diff --git a/components/SizerBase/src/SizerBase.xaml b/components/SizerBase/src/SizerBase.xaml index 59a468eb0..9f6f35b89 100644 --- a/components/SizerBase/src/SizerBase.xaml +++ b/components/SizerBase/src/SizerBase.xaml @@ -1,36 +1,50 @@ - + + xmlns:controls="using:CommunityToolkit.Labs.WinUI"> - - - + + + + + + + + + + + + - - - + + + + + - - - - + 24 + 4 + 2 + 4