UI changes

This commit is contained in:
Niels Laute
2025-11-05 11:12:40 +01:00
parent dbfd69c1b5
commit f57fd585b2
5 changed files with 200 additions and 231 deletions

View File

@@ -15,13 +15,6 @@ namespace ImageResizer.Models
private static readonly CompositeFormat ScaleFormat = CompositeFormat.Parse(Resources.Input_AiScaleFormat); private static readonly CompositeFormat ScaleFormat = CompositeFormat.Parse(Resources.Input_AiScaleFormat);
private int _scale = 2; private int _scale = 2;
[JsonIgnore]
public override string Name
{
get => Resources.Input_AiSuperResolution;
set { /* no-op */ }
}
/// <summary> /// <summary>
/// Gets the formatted scale display string (e.g., "2×"). /// Gets the formatted scale display string (e.g., "2×").
/// </summary> /// </summary>

View File

@@ -19,7 +19,7 @@ namespace ImageResizer.Properties {
// class via a tool like ResGen or Visual Studio. // class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen // To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project. // with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "18.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
public class Resources { public class Resources {
@@ -78,6 +78,33 @@ namespace ImageResizer.Properties {
} }
} }
/// <summary>
/// Looks up a localized string similar to Failed to convert image format for AI processing..
/// </summary>
public static string Error_AiConversionFailed {
get {
return ResourceManager.GetString("Error_AiConversionFailed", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to AI super resolution processing failed: {0}.
/// </summary>
public static string Error_AiProcessingFailed {
get {
return ResourceManager.GetString("Error_AiProcessingFailed", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to AI scaling operation failed..
/// </summary>
public static string Error_AiScalingFailed {
get {
return ResourceManager.GetString("Error_AiScalingFailed", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Height. /// Looks up a localized string similar to Height.
/// </summary> /// </summary>
@@ -105,6 +132,132 @@ namespace ImageResizer.Properties {
} }
} }
/// <summary>
/// Looks up a localized string similar to Current:.
/// </summary>
public static string Input_AiCurrentLabel {
get {
return ResourceManager.GetString("Input_AiCurrentLabel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Checking AI model availability....
/// </summary>
public static string Input_AiModelChecking {
get {
return ResourceManager.GetString("Input_AiModelChecking", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to AI feature is disabled by system settings..
/// </summary>
public static string Input_AiModelDisabledByUser {
get {
return ResourceManager.GetString("Input_AiModelDisabledByUser", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Download.
/// </summary>
public static string Input_AiModelDownloadButton {
get {
return ResourceManager.GetString("Input_AiModelDownloadButton", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Failed to download AI model. Please try again..
/// </summary>
public static string Input_AiModelDownloadFailed {
get {
return ResourceManager.GetString("Input_AiModelDownloadFailed", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Downloading AI model....
/// </summary>
public static string Input_AiModelDownloading {
get {
return ResourceManager.GetString("Input_AiModelDownloading", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to AI model not downloaded. Click Download to get started..
/// </summary>
public static string Input_AiModelNotAvailable {
get {
return ResourceManager.GetString("Input_AiModelNotAvailable", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to AI feature is not supported on this system..
/// </summary>
public static string Input_AiModelNotSupported {
get {
return ResourceManager.GetString("Input_AiModelNotSupported", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to New:.
/// </summary>
public static string Input_AiNewLabel {
get {
return ResourceManager.GetString("Input_AiNewLabel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to {0}×.
/// </summary>
public static string Input_AiScaleFormat {
get {
return ResourceManager.GetString("Input_AiScaleFormat", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Scale.
/// </summary>
public static string Input_AiScaleLabel {
get {
return ResourceManager.GetString("Input_AiScaleLabel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Super resolution.
/// </summary>
public static string Input_AiSuperResolution {
get {
return ResourceManager.GetString("Input_AiSuperResolution", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Upscale images using on-device AI.
/// </summary>
public static string Input_AiSuperResolutionDescription {
get {
return ResourceManager.GetString("Input_AiSuperResolutionDescription", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Unavailable.
/// </summary>
public static string Input_AiUnknownSize {
get {
return ResourceManager.GetString("Input_AiUnknownSize", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to (auto). /// Looks up a localized string similar to (auto).
/// </summary> /// </summary>
@@ -194,187 +347,7 @@ namespace ImageResizer.Properties {
return ResourceManager.GetString("Input_ShrinkOnly.Content", resourceCulture); return ResourceManager.GetString("Input_ShrinkOnly.Content", resourceCulture);
} }
} }
/// <summary>
/// Looks up a localized string similar to AI Super Resolution.
/// </summary>
public static string Input_AiSuperResolution {
get {
return ResourceManager.GetString("Input_AiSuperResolution", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Original size.
/// </summary>
public static string Input_AiOriginalSizeLabel {
get {
return ResourceManager.GetString("Input_AiOriginalSizeLabel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Enhanced size.
/// </summary>
public static string Input_AiEnhancedSizeLabel {
get {
return ResourceManager.GetString("Input_AiEnhancedSizeLabel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Unavailable.
/// </summary>
public static string Input_AiUnknownSize {
get {
return ResourceManager.GetString("Input_AiUnknownSize", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Multiple files selected.
/// </summary>
public static string Input_AiMultipleFiles {
get {
return ResourceManager.GetString("Input_AiMultipleFiles", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to {0}×.
/// </summary>
public static string Input_AiScaleFormat {
get {
return ResourceManager.GetString("Input_AiScaleFormat", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Upscale to {0} times the original size..
/// </summary>
public static string Input_AiScaleHelp {
get {
return ResourceManager.GetString("Input_AiScaleHelp", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Scale.
/// </summary>
public static string Input_AiScaleLabel {
get {
return ResourceManager.GetString("Input_AiScaleLabel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Current.
/// </summary>
public static string Input_AiCurrentLabel {
get {
return ResourceManager.GetString("Input_AiCurrentLabel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to New.
/// </summary>
public static string Input_AiNewLabel {
get {
return ResourceManager.GetString("Input_AiNewLabel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Checking AI model availability...
/// </summary>
public static string Input_AiModelChecking {
get {
return ResourceManager.GetString("Input_AiModelChecking", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to AI model not downloaded. Click Download to get started.
/// </summary>
public static string Input_AiModelNotAvailable {
get {
return ResourceManager.GetString("Input_AiModelNotAvailable", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to AI feature is disabled by system settings.
/// </summary>
public static string Input_AiModelDisabledByUser {
get {
return ResourceManager.GetString("Input_AiModelDisabledByUser", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to AI feature is not supported on this system.
/// </summary>
public static string Input_AiModelNotSupported {
get {
return ResourceManager.GetString("Input_AiModelNotSupported", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Downloading AI model...
/// </summary>
public static string Input_AiModelDownloading {
get {
return ResourceManager.GetString("Input_AiModelDownloading", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Failed to download AI model. Please try again.
/// </summary>
public static string Input_AiModelDownloadFailed {
get {
return ResourceManager.GetString("Input_AiModelDownloadFailed", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Download AI Model.
/// </summary>
public static string Input_AiModelDownloadButton {
get {
return ResourceManager.GetString("Input_AiModelDownloadButton", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to AI super resolution processing failed: {0}.
/// </summary>
public static string Error_AiProcessingFailed {
get {
return ResourceManager.GetString("Error_AiProcessingFailed", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Failed to convert image format for AI processing..
/// </summary>
public static string Error_AiConversionFailed {
get {
return ResourceManager.GetString("Error_AiConversionFailed", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to AI scaling operation failed..
/// </summary>
public static string Error_AiScalingFailed {
get {
return ResourceManager.GetString("Error_AiScalingFailed", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Large. /// Looks up a localized string similar to Large.
/// </summary> /// </summary>

View File

@@ -297,7 +297,7 @@
<value>_Make pictures smaller but not larger</value> <value>_Make pictures smaller but not larger</value>
</data> </data>
<data name="Input_AiSuperResolution" xml:space="preserve"> <data name="Input_AiSuperResolution" xml:space="preserve">
<value>AI Super Resolution</value> <value>Super resolution</value>
</data> </data>
<data name="Input_AiUnknownSize" xml:space="preserve"> <data name="Input_AiUnknownSize" xml:space="preserve">
<value>Unavailable</value> <value>Unavailable</value>
@@ -309,10 +309,10 @@
<value>Scale</value> <value>Scale</value>
</data> </data>
<data name="Input_AiCurrentLabel" xml:space="preserve"> <data name="Input_AiCurrentLabel" xml:space="preserve">
<value>Current</value> <value>Current:</value>
</data> </data>
<data name="Input_AiNewLabel" xml:space="preserve"> <data name="Input_AiNewLabel" xml:space="preserve">
<value>New</value> <value>New:</value>
</data> </data>
<data name="Input_AiModelChecking" xml:space="preserve"> <data name="Input_AiModelChecking" xml:space="preserve">
<value>Checking AI model availability...</value> <value>Checking AI model availability...</value>
@@ -333,7 +333,7 @@
<value>Failed to download AI model. Please try again.</value> <value>Failed to download AI model. Please try again.</value>
</data> </data>
<data name="Input_AiModelDownloadButton" xml:space="preserve"> <data name="Input_AiModelDownloadButton" xml:space="preserve">
<value>Download AI Model</value> <value>Download</value>
</data> </data>
<data name="Error_AiProcessingFailed" xml:space="preserve"> <data name="Error_AiProcessingFailed" xml:space="preserve">
<value>AI super resolution processing failed: {0}</value> <value>AI super resolution processing failed: {0}</value>
@@ -344,4 +344,7 @@
<data name="Error_AiScalingFailed" xml:space="preserve"> <data name="Error_AiScalingFailed" xml:space="preserve">
<value>AI scaling operation failed.</value> <value>AI scaling operation failed.</value>
</data> </data>
<data name="Input_AiSuperResolutionDescription" xml:space="preserve">
<value>Upscale images using on-device AI</value>
</data>
</root> </root>

View File

@@ -111,8 +111,6 @@ namespace ImageResizer.ViewModels
public string AiScaleDisplay => Settings?.AiSize?.ScaleDisplay ?? string.Empty; public string AiScaleDisplay => Settings?.AiSize?.ScaleDisplay ?? string.Empty;
public string AiScaleDescription => FormatLabeledSize(Resources.Input_AiScaleLabel, AiScaleDisplay);
public string CurrentResolutionDescription public string CurrentResolutionDescription
{ {
get => _currentResolutionDescription; get => _currentResolutionDescription;
@@ -269,16 +267,14 @@ namespace ImageResizer.ViewModels
EnsureOriginalDimensionsLoaded(); EnsureOriginalDimensionsLoaded();
var hasConcreteSize = _originalWidth.HasValue && _originalHeight.HasValue; var hasConcreteSize = _originalWidth.HasValue && _originalHeight.HasValue;
var currentValue = hasConcreteSize CurrentResolutionDescription = hasConcreteSize
? FormatDimensions(_originalWidth!.Value, _originalHeight!.Value) ? FormatDimensions(_originalWidth!.Value, _originalHeight!.Value)
: Resources.Input_AiUnknownSize; : Resources.Input_AiUnknownSize;
CurrentResolutionDescription = FormatLabeledSize(Resources.Input_AiCurrentLabel, currentValue);
var scale = Settings.AiSize.Scale; var scale = Settings.AiSize.Scale;
var newValue = hasConcreteSize NewResolutionDescription = hasConcreteSize
? FormatDimensions((long)_originalWidth!.Value * scale, (long)_originalHeight!.Value * scale) ? FormatDimensions((long)_originalWidth!.Value * scale, (long)_originalHeight!.Value * scale)
: Resources.Input_AiUnknownSize; : Resources.Input_AiUnknownSize;
NewResolutionDescription = FormatLabeledSize(Resources.Input_AiNewLabel, newValue);
} }
private static string FormatDimensions(long width, long height) private static string FormatDimensions(long width, long height)
@@ -286,11 +282,6 @@ namespace ImageResizer.ViewModels
return string.Format(CultureInfo.CurrentCulture, "{0} × {1}", width, height); return string.Format(CultureInfo.CurrentCulture, "{0} × {1}", width, height);
} }
private static string FormatLabeledSize(string label, string value)
{
return string.Format(CultureInfo.CurrentCulture, "{0}: {1}", label, value);
}
private void EnsureOriginalDimensionsLoaded() private void EnsureOriginalDimensionsLoaded()
{ {
if (_originalDimensionsLoaded) if (_originalDimensionsLoaded)
@@ -390,7 +381,6 @@ namespace ImageResizer.ViewModels
{ {
OnPropertyChanged(nameof(AiSuperResolutionScale)); OnPropertyChanged(nameof(AiSuperResolutionScale));
OnPropertyChanged(nameof(AiScaleDisplay)); OnPropertyChanged(nameof(AiScaleDisplay));
OnPropertyChanged(nameof(AiScaleDescription));
UpdateAiDetails(); UpdateAiDetails();
} }

View File

@@ -85,15 +85,30 @@
</DataTemplate> </DataTemplate>
<DataTemplate DataType="{x:Type m:AiSize}"> <DataTemplate DataType="{x:Type m:AiSize}">
<Grid VerticalAlignment="Center"> <StackPanel VerticalAlignment="Center" Orientation="Vertical">
<TextBlock FontWeight="SemiBold" Text="{Binding Name}" /> <TextBlock FontWeight="SemiBold" Text="{x:Static p:Resources.Input_AiSuperResolution}" />
</Grid> <TextBlock Text="{x:Static p:Resources.Input_AiSuperResolutionDescription}" />
</StackPanel>
</DataTemplate> </DataTemplate>
</ComboBox.Resources> </ComboBox.Resources>
</ComboBox> </ComboBox>
</StackPanel>
<Grid Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border
Grid.RowSpan="5"
Background="{DynamicResource LayerFillColorDefaultBrush}"
BorderBrush="{DynamicResource CardStrokeColorDefaultBrush}"
BorderThickness="0,1,0,0" />
<!-- AI Configuration Panel --> <!-- AI Configuration Panel -->
<Grid Margin="0,8,0,0"> <Grid Margin="16">
<!-- AI Model Download Prompt --> <!-- AI Model Download Prompt -->
<StackPanel> <StackPanel>
<StackPanel.Style> <StackPanel.Style>
@@ -143,7 +158,11 @@
</Style> </Style>
</StackPanel.Style> </StackPanel.Style>
<TextBlock Style="{StaticResource BodyStrongTextBlockStyle}" Text="{Binding AiScaleDescription}" /> <Grid>
<TextBlock Text="{x:Static p:Resources.Input_AiCurrentLabel}" />
<TextBlock HorizontalAlignment="Right" Text="{Binding AiScaleDisplay}" />
</Grid>
<Slider <Slider
Margin="0,8,0,0" Margin="0,8,0,0"
AutomationProperties.Name="{x:Static p:Resources.Input_AiScaleLabel}" AutomationProperties.Name="{x:Static p:Resources.Input_AiScaleLabel}"
@@ -156,30 +175,21 @@
Ticks="1,2,3,4,5,6,7,8" Ticks="1,2,3,4,5,6,7,8"
Value="{Binding AiSuperResolutionScale, Mode=TwoWay}" /> Value="{Binding AiSuperResolutionScale, Mode=TwoWay}" />
<StackPanel Margin="0,8,0,0" Visibility="{Binding ShowAiSizeDescriptions, Converter={StaticResource BoolValueConverter}}"> <StackPanel Margin="0,16,0,0" Visibility="{Binding ShowAiSizeDescriptions, Converter={StaticResource BoolValueConverter}}">
<TextBlock Style="{StaticResource BodyTextBlockStyle}" Text="{Binding CurrentResolutionDescription}" /> <Grid>
<TextBlock <TextBlock Foreground="{DynamicResource TextFillColorSecondaryBrush}" Text="{x:Static p:Resources.Input_AiCurrentLabel}" />
Margin="0,4,0,0" <TextBlock
Style="{StaticResource BodyTextBlockStyle}" HorizontalAlignment="Right"
Text="{Binding NewResolutionDescription}" /> Foreground="{DynamicResource TextFillColorSecondaryBrush}"
Text="{Binding CurrentResolutionDescription}" />
</Grid>
<Grid Margin="0,8,0,0">
<TextBlock Text="{x:Static p:Resources.Input_AiNewLabel}" />
<TextBlock HorizontalAlignment="Right" Text="{Binding NewResolutionDescription}" />
</Grid>
</StackPanel> </StackPanel>
</StackPanel> </StackPanel>
</Grid> </Grid>
</StackPanel>
<Grid Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border
Grid.RowSpan="5"
Background="{DynamicResource LayerFillColorDefaultBrush}"
BorderBrush="{DynamicResource CardStrokeColorDefaultBrush}"
BorderThickness="0,1,0,0" />
<!-- "Custom" input matrix --> <!-- "Custom" input matrix -->
<Grid Margin="16" Visibility="{Binding ElementName=SizeComboBox, Path=SelectedValue, Converter={StaticResource SizeTypeToVisibilityConverter}}"> <Grid Margin="16" Visibility="{Binding ElementName=SizeComboBox, Path=SelectedValue, Converter={StaticResource SizeTypeToVisibilityConverter}}">