diff --git a/XP.ImageProcessing.RoiControl/Controls/PolygonRoiCanvas.xaml.cs b/XP.ImageProcessing.RoiControl/Controls/PolygonRoiCanvas.xaml.cs index 716eede..28653c9 100644 --- a/XP.ImageProcessing.RoiControl/Controls/PolygonRoiCanvas.xaml.cs +++ b/XP.ImageProcessing.RoiControl/Controls/PolygonRoiCanvas.xaml.cs @@ -629,7 +629,9 @@ namespace XP.ImageProcessing.RoiControl.Controls g.FullLine = new Line { Stroke = Brushes.Red, StrokeThickness = 1, IsHitTestVisible = false }; g.FillLine = new Line { Stroke = Brushes.Lime, StrokeThickness = 2, IsHitTestVisible = false }; - g.Label = new TextBlock { FontSize = 13, FontWeight = FontWeights.Bold, IsHitTestVisible = false }; + g.Label = new TextBlock { FontSize = 13, FontWeight = FontWeights.Bold, Cursor = Cursors.Hand }; + g.Label.SetValue(ContextMenuService.IsEnabledProperty, false); + g.Label.MouseRightButtonUp += (s, ev) => { ShowTHTLimitEditor(g); ev.Handled = true; }; g.DotE1 = CreateMDot(Brushes.DodgerBlue); g.DotE2 = CreateMDot(Brushes.Cyan); @@ -851,6 +853,94 @@ namespace XP.ImageProcessing.RoiControl.Controls } } + // ── 填锡率阈值编辑 ── + + private TextBox _thtEditBox; + private TextBlock _thtEditLabel; + + private void RemoveTHTEditor() + { + if (_thtEditBox != null && _measureOverlay != null) + _measureOverlay.Children.Remove(_thtEditBox); + if (_thtEditLabel != null && _measureOverlay != null) + _measureOverlay.Children.Remove(_thtEditLabel); + _thtEditBox = null; + _thtEditLabel = null; + } + + private void ShowTHTLimitEditor(Models.FillRateGroup g) + { + if (_measureOverlay == null) return; + + // 移除旧的编辑框 + if (_thtEditBox != null) + { + _measureOverlay.Children.Remove(_thtEditBox); + _thtEditBox = null; + } + if (_thtEditLabel != null) + { + _measureOverlay.Children.Remove(_thtEditLabel); + _thtEditLabel = null; + } + + double left = Canvas.GetLeft(g.Label); + double top = Canvas.GetTop(g.Label) + 22; + + // 参数名称提示 + _thtEditLabel = new TextBlock + { + Text = "THTLimit(%):", + FontSize = 11, + Foreground = Brushes.White, + Background = new SolidColorBrush(Color.FromArgb(180, 0, 0, 0)), + Padding = new Thickness(3, 1, 3, 1) + }; + Canvas.SetLeft(_thtEditLabel, left); + Canvas.SetTop(_thtEditLabel, top); + _measureOverlay.Children.Add(_thtEditLabel); + + // 输入框 + _thtEditBox = new TextBox + { + Text = g.THTLimit.ToString("F1"), + Width = 60, + Height = 22, + FontSize = 12, + Background = Brushes.White, + BorderBrush = Brushes.Orange, + BorderThickness = new Thickness(2), + Padding = new Thickness(2, 0, 2, 0) + }; + Canvas.SetLeft(_thtEditBox, left + 80); + Canvas.SetTop(_thtEditBox, top); + _measureOverlay.Children.Add(_thtEditBox); + _thtEditBox.Focus(); + _thtEditBox.SelectAll(); + + // 回车确认 + _thtEditBox.KeyDown += (s, ev) => + { + if (ev.Key == System.Windows.Input.Key.Enter) + { + if (double.TryParse(_thtEditBox.Text, out double val)) + { + g.THTLimit = System.Math.Clamp(val, 0, 100); + g.UpdateVisuals(); + RaiseMeasureCompleted(g.E3, g.E4, g.FillRate, MeasureCount, "FillRate"); + } + RemoveTHTEditor(); + } + else if (ev.Key == System.Windows.Input.Key.Escape) + { + RemoveTHTEditor(); + } + }; + + // 失焦也关闭 + _thtEditBox.LostFocus += (s, ev) => RemoveTHTEditor(); + } + // ── 事件 ── public static readonly RoutedEvent MeasureCompletedEvent = diff --git a/XP.ImageProcessing.RoiControl/Models/FillRateGroup.cs b/XP.ImageProcessing.RoiControl/Models/FillRateGroup.cs index 3b2d6b1..34e789c 100644 --- a/XP.ImageProcessing.RoiControl/Models/FillRateGroup.cs +++ b/XP.ImageProcessing.RoiControl/Models/FillRateGroup.cs @@ -100,7 +100,7 @@ namespace XP.ImageProcessing.RoiControl.Models double rate = FillRate; string cls = Classification; - Label.Text = $"{rate:F1}% {cls}"; + Label.Text = $"Fill: {rate:F1}% | THTLimit: {THTLimit:F1}% | {cls}"; Label.Foreground = cls == "PASS" ? Brushes.Lime : Brushes.Red; double labelX = Math.Max(Math.Max(E1.X, E2.X), Math.Max(E3.X, E4.X)) + 15; double labelY = (E1.Y + E2.Y) / 2;