mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-03 09:46:54 +02:00
[ImageResizer] Fix issues with blank Width and Height controls (#37373)
* Allow custom preset's dimensions to be blank in the UI while still persisted as 0. * XAML formatting - reorder namespaces. * Add "(auto)" text to zero-value Width/Height in Settings. Ensure Width and Height fields in flyout are formatted to empty when their value is 0.
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Converters;
|
||||
|
||||
/// <summary>
|
||||
/// Converts between double and string for text-based controls bound to Width or Height fields.
|
||||
/// Optionally returns localized "Auto" text when the underlying value is 0, letting the UI show,
|
||||
/// for example "(auto) x 1024 pixels".
|
||||
/// </summary>
|
||||
public sealed partial class ImageResizerDoubleToAutoConverter : IValueConverter
|
||||
{
|
||||
private static readonly string AutoText =
|
||||
Helpers.ResourceLoaderInstance.ResourceLoader.GetString("ImageResizer_AutoText");
|
||||
|
||||
/// <summary>
|
||||
/// Converts a double to a string, optionally showing "Auto" for 0 values. NaN values are
|
||||
/// converted to empty strings.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to convert from <see cref="double"/> to
|
||||
/// <see cref="string"/>.</param>
|
||||
/// <param name="targetType">The conversion target type. <see cref="string"/> here.</param>
|
||||
/// <param name="parameter">Set to "Auto" to return the localized "Auto" string if the
|
||||
/// value is 0.</param>
|
||||
/// <param name="language">Ignored.</param>
|
||||
/// <returns>The string representation of the passed-in value.</returns>
|
||||
public object Convert(object value, Type targetType, object parameter, string language) =>
|
||||
value switch
|
||||
{
|
||||
double d => d switch
|
||||
{
|
||||
double.NaN => "0",
|
||||
0 => (string)parameter == "Auto" ? AutoText : "0",
|
||||
_ => d.ToString(CultureInfo.CurrentCulture),
|
||||
},
|
||||
|
||||
_ => "0",
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Converts the string representation back to a double, returning 0 if the string is empty,
|
||||
/// null or not a valid number in the specified culture.
|
||||
/// </summary>
|
||||
/// <param name="value">The string value to convert.</param>
|
||||
/// <param name="targetType">The conversion target type. <see cref="double"/> here.</param>
|
||||
/// <param name="parameter">Converter parameter. Unused.</param>
|
||||
/// <param name="language">Ignored.</param>
|
||||
/// <returns>The corresponding double value.</returns>
|
||||
public object ConvertBack(object value, Type targetType, object parameter, string language) =>
|
||||
value switch
|
||||
{
|
||||
null or "" => 0.0,
|
||||
string text when double.TryParse(text, NumberStyles.Any, CultureInfo.CurrentCulture, out double result) => result,
|
||||
_ => 0.0,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Converters;
|
||||
|
||||
public partial class ImageResizerNumberBoxValueConverter : IValueConverter
|
||||
{
|
||||
/// <summary>
|
||||
/// Converts the underlying double value to a display-friendly format. Ensures that NaN values
|
||||
/// are not propagated to the UI.
|
||||
/// </summary>
|
||||
public object Convert(object value, Type targetType, object parameter, string language) =>
|
||||
value is double d && double.IsNaN(d) ? 0.0 : value;
|
||||
|
||||
/// <summary>
|
||||
/// Converts the user input back to the underlying double value. If the input is not a valid
|
||||
/// number, a double with value 0 is returned.
|
||||
/// </summary>
|
||||
public object ConvertBack(object value, Type targetType, object parameter, string language) =>
|
||||
value switch
|
||||
{
|
||||
null => 0.0,
|
||||
double d when double.IsNaN(d) => 0.0,
|
||||
string str when !double.TryParse(str, out _) => 0.0,
|
||||
_ => value,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Converters;
|
||||
|
||||
public partial class ImageResizerZeroToEmptyStringNumberFormatter
|
||||
{
|
||||
public string Format(long value) => throw new NotImplementedException();
|
||||
|
||||
public string Format(ulong value) => throw new NotImplementedException();
|
||||
|
||||
public string Format(double value) => throw new NotImplementedException();
|
||||
|
||||
public string FormatDouble(double? value) => value switch
|
||||
{
|
||||
null => string.Empty,
|
||||
0 => string.Empty,
|
||||
_ => value.Value.ToString(CultureInfo.CurrentCulture),
|
||||
};
|
||||
|
||||
public double? ParseDouble(string text)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(text))
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
return double.TryParse(text, NumberStyles.Any, CultureInfo.CurrentCulture, out double result) ? result : 0.0;
|
||||
}
|
||||
|
||||
public long? ParseInt(string text) => throw new NotImplementedException();
|
||||
|
||||
public ulong? ParseUInt(string text) => throw new NotImplementedException();
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Controls;
|
||||
|
||||
public partial class ImageResizerDimensionsNumberBox : NumberBox
|
||||
{
|
||||
public ImageResizerDimensionsNumberBox()
|
||||
{
|
||||
this.Loaded += (_, _) => UpdateDisplayText();
|
||||
|
||||
this.ValueChanged += (_, _) => UpdateDisplayText();
|
||||
|
||||
this.GotFocus += (s, e) =>
|
||||
{
|
||||
// Show "0" in the UI when focused on the empty value. This ensures that the spinbutton
|
||||
// controls are usable.
|
||||
if (Value is double.NaN)
|
||||
{
|
||||
Value = 0.0;
|
||||
}
|
||||
};
|
||||
|
||||
this.LostFocus += (_, _) => UpdateDisplayText();
|
||||
}
|
||||
|
||||
private void UpdateDisplayText()
|
||||
{
|
||||
if (FocusState == FocusState.Unfocused && Value == 0)
|
||||
{
|
||||
Text = string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,9 @@
|
||||
<converters:ImageResizerUnitToStringConverter x:Key="ImageResizerUnitToStringConverter" />
|
||||
<converters:ImageResizerUnitToIntConverter x:Key="ImageResizerUnitToIntConverter" />
|
||||
<converters:ImageResizerSizeToAccessibleTextConverter x:Key="ImageResizerSizeToAccessibleTextConverter" />
|
||||
<converters:ImageResizerDoubleToAutoConverter x:Key="ImageResizerDoubleToAutoConverter" />
|
||||
<converters:ImageResizerNumberBoxValueConverter x:Key="ImageResizerNumberBoxValueConverter" />
|
||||
<converters:ImageResizerZeroToEmptyStringNumberFormatter x:Key="ImageResizerZeroToEmptyStringNumberFormatter" />
|
||||
<toolkitconverters:BoolToObjectConverter
|
||||
x:Key="BoolToComboBoxIndexConverter"
|
||||
FalseValue="1"
|
||||
@@ -78,7 +81,7 @@
|
||||
Margin="0,0,4,0"
|
||||
FontWeight="SemiBold"
|
||||
Style="{ThemeResource SecondaryTextStyle}"
|
||||
Text="{x:Bind Width, Mode=OneWay}" />
|
||||
Text="{x:Bind Width, Mode=OneWay, Converter={StaticResource ImageResizerDoubleToAutoConverter}, ConverterParameter=Auto}" />
|
||||
<TextBlock
|
||||
Margin="0,5,4,0"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
@@ -91,7 +94,7 @@
|
||||
Margin="0,0,4,0"
|
||||
FontWeight="SemiBold"
|
||||
Style="{ThemeResource SecondaryTextStyle}"
|
||||
Text="{x:Bind Height, Mode=OneWay}"
|
||||
Text="{x:Bind Height, Mode=OneWay, Converter={StaticResource ImageResizerDoubleToAutoConverter}, ConverterParameter=Auto}"
|
||||
Visibility="{x:Bind IsHeightUsed, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}" />
|
||||
<TextBlock
|
||||
Margin="0,0,4,0"
|
||||
@@ -136,20 +139,20 @@
|
||||
</ComboBox>
|
||||
|
||||
<StackPanel Orientation="Horizontal" Spacing="8">
|
||||
<NumberBox
|
||||
<controls:ImageResizerDimensionsNumberBox
|
||||
x:Uid="ImageResizer_Width"
|
||||
Width="116"
|
||||
Minimum="0"
|
||||
SpinButtonPlacementMode="Compact"
|
||||
Value="{x:Bind Width, Mode=TwoWay}" />
|
||||
Value="{x:Bind Width, Mode=TwoWay, Converter={StaticResource ImageResizerNumberBoxValueConverter}}" />
|
||||
|
||||
<NumberBox
|
||||
<controls:ImageResizerDimensionsNumberBox
|
||||
x:Uid="ImageResizer_Height"
|
||||
Width="116"
|
||||
Minimum="0"
|
||||
SpinButtonPlacementMode="Compact"
|
||||
Visibility="{x:Bind IsHeightUsed, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}"
|
||||
Value="{x:Bind Height, Mode=TwoWay}" />
|
||||
Value="{x:Bind Height, Mode=TwoWay, Converter={StaticResource ImageResizerNumberBoxValueConverter}}" />
|
||||
</StackPanel>
|
||||
|
||||
<ComboBox
|
||||
|
||||
@@ -1193,6 +1193,10 @@
|
||||
<value>TIFF compression</value>
|
||||
<comment>{Locked="TIFF"}</comment>
|
||||
</data>
|
||||
<data name="ImageResizer_AutoText" xml:space="preserve">
|
||||
<value>(auto)</value>
|
||||
<comment>Displayed on the preset card when the Width or Height property is zero. The same as "Input_Auto" in the ImageResizerUI project's resources.</comment>
|
||||
</data>
|
||||
<data name="File.Header" xml:space="preserve">
|
||||
<value>File</value>
|
||||
<comment>as in a computer file</comment>
|
||||
|
||||
Reference in New Issue
Block a user