From a483144d29f35a6f9228e877176939612266c02f Mon Sep 17 00:00:00 2001 From: "zhengxuan.zhang" Date: Wed, 6 May 2026 13:25:18 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4=E6=B5=81=E6=B0=B4=E7=BA=BF?= =?UTF-8?q?=E7=AE=97=E5=AD=90=E5=8F=82=E6=95=B0=E5=8C=BA=20=E6=BB=91?= =?UTF-8?q?=E5=9D=97=E6=8E=A7=E4=BB=B6=E7=9A=84=E5=A4=A7=E5=B0=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ProcessorParameterControl.xaml | 8 +- .../ProcessorParameterControl.xaml.cs | 62 ++++++++---- .../ImageProcessing/ProcessorParameterVM.cs | 98 ++++++++++++++++++- XplorePlane/ViewModels/Main/MainViewModel.cs | 2 +- XplorePlane/Views/Cnc/CncPageView.xaml | 8 +- .../ImageProcessingPanelView.xaml | 6 +- .../ImageProcessing/PipelineEditorView.xaml | 46 ++++++++- 7 files changed, 199 insertions(+), 31 deletions(-) diff --git a/XP.ImageProcessing.CfgControl/ProcessorParameterControl.xaml b/XP.ImageProcessing.CfgControl/ProcessorParameterControl.xaml index aedfcc7..ab6e037 100644 --- a/XP.ImageProcessing.CfgControl/ProcessorParameterControl.xaml +++ b/XP.ImageProcessing.CfgControl/ProcessorParameterControl.xaml @@ -16,8 +16,8 @@ Background="Transparent" BorderBrush="#FFD5DFE5" BorderThickness="1" - Padding="10" - Margin="0,0,0,10"> + Padding="8" + Margin="0,0,0,8"> - + - \ No newline at end of file + diff --git a/XP.ImageProcessing.CfgControl/ProcessorParameterControl.xaml.cs b/XP.ImageProcessing.CfgControl/ProcessorParameterControl.xaml.cs index 409b0db..ee88e11 100644 --- a/XP.ImageProcessing.CfgControl/ProcessorParameterControl.xaml.cs +++ b/XP.ImageProcessing.CfgControl/ProcessorParameterControl.xaml.cs @@ -143,12 +143,15 @@ public partial class ProcessorParameterControl : UserControl var textBox = new TextBox { Text = param.Value.ToString(), - Width = 100, - HorizontalAlignment = HorizontalAlignment.Left + Width = 56, + MinWidth = 56, + HorizontalContentAlignment = HorizontalAlignment.Center, + VerticalContentAlignment = VerticalAlignment.Center }; if (param.MinValue != null && param.MaxValue != null) { + var rangeGrid = CreateRangeEditorContainer(); var slider = new Slider { Minimum = Convert.ToDouble(param.MinValue), @@ -156,7 +159,8 @@ public partial class ProcessorParameterControl : UserControl Value = Convert.ToDouble(param.Value), TickFrequency = 1, IsSnapToTickEnabled = true, - Margin = new Thickness(0, 0, 0, 5) + MinWidth = 120, + VerticalAlignment = VerticalAlignment.Center }; slider.ValueChanged += (s, e) => @@ -181,7 +185,11 @@ public partial class ProcessorParameterControl : UserControl } }; - panel.Children.Add(slider); + Grid.SetColumn(slider, 0); + Grid.SetColumn(textBox, 2); + rangeGrid.Children.Add(slider); + rangeGrid.Children.Add(textBox); + panel.Children.Add(rangeGrid); } else { @@ -193,9 +201,9 @@ public partial class ProcessorParameterControl : UserControl OnParameterChanged(); } }; - } - panel.Children.Add(textBox); + panel.Children.Add(textBox); + } return panel; } @@ -211,19 +219,23 @@ public partial class ProcessorParameterControl : UserControl var textBox = new TextBox { Text = Convert.ToDouble(param.Value).ToString("F2"), - Width = 100, - HorizontalAlignment = HorizontalAlignment.Left + Width = 56, + MinWidth = 56, + HorizontalContentAlignment = HorizontalAlignment.Center, + VerticalContentAlignment = VerticalAlignment.Center }; if (param.MinValue != null && param.MaxValue != null) { + var rangeGrid = CreateRangeEditorContainer(); var slider = new Slider { Minimum = Convert.ToDouble(param.MinValue), Maximum = Convert.ToDouble(param.MaxValue), Value = Convert.ToDouble(param.Value), TickFrequency = 0.1, - Margin = new Thickness(0, 0, 0, 5) + MinWidth = 120, + VerticalAlignment = VerticalAlignment.Center }; slider.ValueChanged += (s, e) => @@ -248,7 +260,11 @@ public partial class ProcessorParameterControl : UserControl } }; - panel.Children.Add(slider); + Grid.SetColumn(slider, 0); + Grid.SetColumn(textBox, 2); + rangeGrid.Children.Add(slider); + rangeGrid.Children.Add(textBox); + panel.Children.Add(rangeGrid); } else { @@ -260,9 +276,9 @@ public partial class ProcessorParameterControl : UserControl OnParameterChanged(); } }; - } - panel.Children.Add(textBox); + panel.Children.Add(textBox); + } return panel; } @@ -302,8 +318,8 @@ public partial class ProcessorParameterControl : UserControl var comboBox = new ComboBox { Margin = new Thickness(0, 5, 0, 0), - Width = 200, - HorizontalAlignment = HorizontalAlignment.Left + MinWidth = 160, + HorizontalAlignment = HorizontalAlignment.Stretch }; if (param.Options != null) @@ -344,8 +360,8 @@ public partial class ProcessorParameterControl : UserControl { Text = param.Value?.ToString() ?? "", Margin = new Thickness(0, 5, 0, 0), - Width = 200, - HorizontalAlignment = HorizontalAlignment.Left + MinWidth = 160, + HorizontalAlignment = HorizontalAlignment.Stretch }; textBox.TextChanged += (s, e) => @@ -374,4 +390,16 @@ public partial class ProcessorParameterControl : UserControl pnlParameters.Children.Clear(); UpdateNoProcessorText(); } -} \ No newline at end of file + + private static Grid CreateRangeEditorContainer() + { + var grid = new Grid + { + Margin = new Thickness(0, 0, 0, 4) + }; + grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) }); + grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(6) }); + grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto }); + return grid; + } +} diff --git a/XplorePlane/ViewModels/ImageProcessing/ProcessorParameterVM.cs b/XplorePlane/ViewModels/ImageProcessing/ProcessorParameterVM.cs index 019aaca..c70fc83 100644 --- a/XplorePlane/ViewModels/ImageProcessing/ProcessorParameterVM.cs +++ b/XplorePlane/ViewModels/ImageProcessing/ProcessorParameterVM.cs @@ -39,7 +39,15 @@ namespace XplorePlane.ViewModels public string ParameterType { get; } public bool HasOptions => Options is { Length: > 0 }; public bool IsBool => ParameterType == "bool"; - public bool IsTextInput => !IsBool && !HasOptions; + public bool IsNumeric => ParameterType is "int" or "double"; + public bool HasRange => IsNumeric && MinValue != null && MaxValue != null; + public bool IsSliderInput => HasRange; + public bool IsTextInput => !IsBool && !HasOptions && !IsSliderInput; + + public double SliderMinimum => TryConvertToDouble(MinValue, out var minValue) ? minValue : 0d; + public double SliderMaximum => TryConvertToDouble(MaxValue, out var maxValue) ? maxValue : 100d; + public double SliderTickFrequency => ResolveTickFrequency(); + public bool IsIntegerSlider => ParameterType == "int"; public bool IsValueValid { @@ -60,10 +68,46 @@ namespace XplorePlane.ViewModels RaisePropertyChanged(nameof(Value)); RaisePropertyChanged(nameof(BoolValue)); RaisePropertyChanged(nameof(SelectedOption)); + RaisePropertyChanged(nameof(SliderValue)); + RaisePropertyChanged(nameof(DisplayValueText)); } } } + public double SliderValue + { + get => TryConvertToDouble(_value, out var sliderValue) ? sliderValue : SliderMinimum; + set + { + if (!IsSliderInput) + { + return; + } + + Value = ParameterType == "int" + ? (object)Convert.ToInt32(Math.Round(value, MidpointRounding.AwayFromZero), CultureInfo.InvariantCulture) + : Math.Round(value, ResolveDecimalPlaces(), MidpointRounding.AwayFromZero); + } + } + + public string DisplayValueText + { + get + { + if (ParameterType == "int" && TryConvertToInt(_value, out var intValue)) + { + return intValue.ToString(CultureInfo.InvariantCulture); + } + + if (ParameterType == "double" && TryConvertToDouble(_value, out var doubleValue)) + { + return doubleValue.ToString($"F{ResolveDecimalPlaces()}", CultureInfo.InvariantCulture); + } + + return Convert.ToString(_value, CultureInfo.InvariantCulture) ?? string.Empty; + } + } + public bool BoolValue { get => ParameterType == "bool" && TryConvertToBool(_value, out var boolValue) && boolValue; @@ -154,6 +198,58 @@ namespace XplorePlane.ViewModels return true; } + private double ResolveTickFrequency() + { + if (!HasRange) + { + return 1d; + } + + if (ParameterType == "int") + { + return 1d; + } + + double range = SliderMaximum - SliderMinimum; + if (range <= 1d) + { + return 0.01d; + } + + if (range <= 10d) + { + return 0.1d; + } + + return 1d; + } + + private int ResolveDecimalPlaces() + { + if (ParameterType == "int") + { + return 0; + } + + double tick = SliderTickFrequency; + if (tick >= 1d) + { + return 0; + } + + if (tick >= 0.1d) + { + return 1; + } + + if (tick >= 0.01d) + { + return 2; + } + + return 3; + } + private static string NormalizeNumericText(string value) { return value.Trim().TrimEnd('、', ',', ',', '。', '.', ';', ';', ':', ':'); diff --git a/XplorePlane/ViewModels/Main/MainViewModel.cs b/XplorePlane/ViewModels/Main/MainViewModel.cs index dff8675..1ac944f 100644 --- a/XplorePlane/ViewModels/Main/MainViewModel.cs +++ b/XplorePlane/ViewModels/Main/MainViewModel.cs @@ -23,7 +23,7 @@ namespace XplorePlane.ViewModels { public class MainViewModel : BindableBase { - private const double CncEditorHostWidth = 402d; + private const double CncEditorHostWidth = 452d; private readonly ILoggerService _logger; private readonly IContainerProvider _containerProvider; diff --git a/XplorePlane/Views/Cnc/CncPageView.xaml b/XplorePlane/Views/Cnc/CncPageView.xaml index 18aef55..092a6b7 100644 --- a/XplorePlane/Views/Cnc/CncPageView.xaml +++ b/XplorePlane/Views/Cnc/CncPageView.xaml @@ -10,7 +10,7 @@ xmlns:views="clr-namespace:XplorePlane.Views" xmlns:vm="clr-namespace:XplorePlane.ViewModels.Cnc" d:DesignHeight="760" - d:DesignWidth="402" + d:DesignWidth="452" prism:ViewModelLocator.AutoWireViewModel="True" mc:Ignorable="d"> @@ -114,8 +114,8 @@ - + diff --git a/XplorePlane/Views/ImageProcessing/ImageProcessingPanelView.xaml b/XplorePlane/Views/ImageProcessing/ImageProcessingPanelView.xaml index 45801da..212dbd1 100644 --- a/XplorePlane/Views/ImageProcessing/ImageProcessingPanelView.xaml +++ b/XplorePlane/Views/ImageProcessing/ImageProcessingPanelView.xaml @@ -63,7 +63,7 @@ - + @@ -145,7 +145,7 @@ - + - \ No newline at end of file + diff --git a/XplorePlane/Views/ImageProcessing/PipelineEditorView.xaml b/XplorePlane/Views/ImageProcessing/PipelineEditorView.xaml index 90289e3..cfd7525 100644 --- a/XplorePlane/Views/ImageProcessing/PipelineEditorView.xaml +++ b/XplorePlane/Views/ImageProcessing/PipelineEditorView.xaml @@ -317,9 +317,53 @@ Text="{Binding DisplayName}" TextTrimming="CharacterEllipsis" /> + + + + + + + + + + + + + + + +