-
Notifications
You must be signed in to change notification settings - Fork 760
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add support for Scale property in CornerRadiusFilterConverter
- Loading branch information
1 parent
340d147
commit 089f344
Showing
1 changed file
with
112 additions
and
54 deletions.
There are no files selected for viewing
166 changes: 112 additions & 54 deletions
166
src/Uno.UI/Microsoft/UI/Xaml/Controls/Primitives/CornerRadiusFilterConverter.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,75 +1,133 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Text; | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. See LICENSE in the project root for license information. | ||
// MUX Reference CornerRadiusFilterConverter.cpp, commit 22e5052 | ||
|
||
#nullable enable | ||
|
||
using System; | ||
using Windows.UI.Xaml; | ||
using Windows.UI.Xaml.Data; | ||
|
||
namespace Microsoft.UI.Xaml.Controls.Primitives | ||
namespace Microsoft.UI.Xaml.Controls.Primitives; | ||
|
||
/// <summary> | ||
/// Converts an existing CornerRadius struct to a new CornerRadius struct, with filters applied | ||
/// to extract only the specified fields, leaving the others set to 0. | ||
/// </summary> | ||
public partial class CornerRadiusFilterConverter : DependencyObject, IValueConverter | ||
{ | ||
public partial class CornerRadiusFilterConverter : DependencyObject, IValueConverter | ||
/// <summary> | ||
/// Gets or sets the type of the filter applied to the CornerRadiusFilterConverter. | ||
/// </summary> | ||
public CornerRadiusFilterKind Filter | ||
{ | ||
public static DependencyProperty FilterProperty { get; } = DependencyProperty.Register( | ||
nameof(Filter), typeof(CornerRadiusFilterKind), typeof(CornerRadiusFilterConverter), new FrameworkPropertyMetadata(CornerRadiusFilterKind.None)); | ||
get => (CornerRadiusFilterKind)GetValue(FilterProperty); | ||
set => SetValue(FilterProperty, value); | ||
} | ||
|
||
public CornerRadiusFilterKind Filter | ||
{ | ||
get => (CornerRadiusFilterKind)GetValue(FilterProperty); | ||
set => SetValue(FilterProperty, value); | ||
} | ||
/// <summary> | ||
/// Identifies the Filter dependency property. | ||
/// </summary> | ||
public static DependencyProperty FilterProperty { get; } = | ||
DependencyProperty.Register( | ||
nameof(Filter), | ||
typeof(CornerRadiusFilterKind), | ||
typeof(CornerRadiusFilterConverter), | ||
new FrameworkPropertyMetadata(CornerRadiusFilterKind.None)); | ||
|
||
private static CornerRadius Convert(CornerRadius radius, CornerRadiusFilterKind filterKind) | ||
{ | ||
var result = radius; | ||
/// <summary> | ||
/// Gets or sets the scale multiplier applied to the CornerRadiusFilterConverter. | ||
/// </summary> | ||
public double Scale | ||
{ | ||
get => (double)GetValue(ScaleProperty); | ||
set => SetValue(ScaleProperty, value); | ||
} | ||
|
||
switch (filterKind) | ||
{ | ||
case CornerRadiusFilterKind.Top: | ||
result.BottomLeft = 0; | ||
result.BottomRight = 0; | ||
break; | ||
case CornerRadiusFilterKind.Right: | ||
result.TopLeft = 0; | ||
result.BottomLeft = 0; | ||
break; | ||
case CornerRadiusFilterKind.Bottom: | ||
result.TopLeft = 0; | ||
result.TopRight = 0; | ||
break; | ||
case CornerRadiusFilterKind.Left: | ||
result.TopRight = 0; | ||
result.BottomRight = 0; | ||
break; | ||
} | ||
/// <summary> | ||
/// Identifies the Scale dependency property. | ||
/// </summary> | ||
public static DependencyProperty ScaleProperty { get; } = | ||
DependencyProperty.Register( | ||
nameof(Scale), | ||
typeof(double), | ||
typeof(CornerRadiusFilterConverter), | ||
new FrameworkPropertyMetadata(1.0)); | ||
|
||
return result; | ||
private static CornerRadius Convert(CornerRadius radius, CornerRadiusFilterKind filterKind) | ||
{ | ||
var result = radius; | ||
|
||
switch (filterKind) | ||
{ | ||
case CornerRadiusFilterKind.Top: | ||
result.BottomLeft = 0; | ||
result.BottomRight = 0; | ||
break; | ||
case CornerRadiusFilterKind.Right: | ||
result.TopLeft = 0; | ||
result.BottomLeft = 0; | ||
break; | ||
case CornerRadiusFilterKind.Bottom: | ||
result.TopLeft = 0; | ||
result.TopRight = 0; | ||
break; | ||
case CornerRadiusFilterKind.Left: | ||
result.TopRight = 0; | ||
result.BottomRight = 0; | ||
break; | ||
} | ||
|
||
private static double GetDoubleValue(CornerRadius radius, CornerRadiusFilterKind filterKind) | ||
=> | ||
filterKind switch | ||
{ | ||
CornerRadiusFilterKind.TopLeftValue => radius.TopLeft, | ||
CornerRadiusFilterKind.BottomRightValue => radius.BottomRight, | ||
_ => 0d | ||
}; | ||
return result; | ||
} | ||
|
||
private static double GetDoubleValue(CornerRadius radius, CornerRadiusFilterKind filterKind) => | ||
filterKind switch | ||
{ | ||
CornerRadiusFilterKind.TopLeftValue => radius.TopLeft, | ||
CornerRadiusFilterKind.BottomRightValue => radius.BottomRight, | ||
_ => 0d | ||
}; | ||
|
||
public object Convert(object value, Type targetType, object parameter, string language) | ||
/// <summary> | ||
/// Converts the source CornerRadius by extracting only the fields specified | ||
/// by the Filter and leaving others set to 0. | ||
/// </summary> | ||
/// <param name="value">The source CornerRadius being passed to the target.</param> | ||
/// <param name="targetType">The type of the target property. Part of the IValueConverter.Convert interface method, but not used.</param> | ||
/// <param name="parameter">An optional parameter to be used in the converter logic. Part of the IValueConverter.Convert interface method, but not used.</param> | ||
/// <param name="language">The language of the conversion. Part of the IValueConverter.Convert interface method, but not used.</param> | ||
/// <returns>The converted CornerRadius/double value to be passed to the target dependency property.</returns> | ||
public object? Convert(object? value, Type targetType, object? parameter, string language) | ||
{ | ||
if (value is CornerRadius cornerRadius) | ||
{ | ||
var filter = Filter; | ||
var scale = Scale; | ||
if (!double.IsNaN(scale)) | ||
{ | ||
cornerRadius.TopLeft *= scale; | ||
cornerRadius.TopRight *= scale; | ||
cornerRadius.BottomLeft *= scale; | ||
cornerRadius.BottomRight *= scale; | ||
} | ||
|
||
if (value is CornerRadius cornerRadius) | ||
var filterType = Filter; | ||
if (filterType == CornerRadiusFilterKind.TopLeftValue || | ||
filterType == CornerRadiusFilterKind.BottomRightValue) | ||
{ | ||
if (filter == CornerRadiusFilterKind.TopLeftValue || filter == CornerRadiusFilterKind.BottomRightValue) | ||
{ | ||
return GetDoubleValue(cornerRadius, filter); | ||
} | ||
return Convert(cornerRadius, filter); | ||
return GetDoubleValue(cornerRadius, filterType); | ||
} | ||
|
||
return null; | ||
return Convert(cornerRadius, filterType); | ||
} | ||
|
||
public object ConvertBack(object value, Type targetType, object parameter, string language) => | ||
throw new NotSupportedException(); | ||
return null; | ||
} | ||
|
||
/// <summary> | ||
/// Not implemented. | ||
/// </summary> | ||
/// <exception cref="NotImplementedException">Always thrown when called.</exception> | ||
public object? ConvertBack(object? value, Type targetType, object? parameter, string language) => | ||
throw new NotImplementedException(); | ||
} |