CNC 标记右键显示 Mark 菜单
人工标记右键显示 Mark 菜单 统一提供编辑属性、显示关联图像、删除、恢复位置等菜单 继续屏蔽底层 RoiCanvas 的缩放/保存菜单,避免两个菜单同时出现
This commit is contained in:
@@ -758,7 +758,13 @@ namespace XP.ImageProcessing.RoiControl.Controls
|
||||
ClearOverlayLayer(layer);
|
||||
if (overlayCanvas == null) return;
|
||||
|
||||
overlayCanvas.IsHitTestVisible = false;
|
||||
// 结果/辅助叠加层默认不参与命中测试;检查标记层例外,保留其自身的命中配置,
|
||||
// 以便标记图标可以处理右键,而空白区域仍由 Background=null 穿透到底层画布。
|
||||
if (layer != ViewportOverlayLayer.InspectionMarks)
|
||||
overlayCanvas.IsHitTestVisible = false;
|
||||
System.Diagnostics.Debug.WriteLine(
|
||||
$"[ViewportMouse] AttachOverlay layer={layer}, hitTest={overlayCanvas.IsHitTestVisible}, " +
|
||||
$"background={overlayCanvas.Background ?? System.Windows.Media.Brushes.Transparent}");
|
||||
overlayCanvas.SetBinding(Canvas.WidthProperty, new System.Windows.Data.Binding("CanvasWidth") { Source = this });
|
||||
overlayCanvas.SetBinding(Canvas.HeightProperty, new System.Windows.Data.Binding("CanvasHeight") { Source = this });
|
||||
if (layer == ViewportOverlayLayer.InspectionMarks)
|
||||
@@ -2746,6 +2752,9 @@ namespace XP.ImageProcessing.RoiControl.Controls
|
||||
|
||||
private void Canvas_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(
|
||||
$"[ViewportMouse] RoiCanvas.MouseRightButtonDown source={e.OriginalSource?.GetType().Name}, " +
|
||||
$"handled={e.Handled}, point={e.GetPosition(mainCanvas)}");
|
||||
// BGA 模式下右键切换气泡/焊球
|
||||
if (CurrentMeasureMode == Models.MeasureMode.BgaVoid && _bgaCurrent != null)
|
||||
{
|
||||
@@ -2760,6 +2769,9 @@ namespace XP.ImageProcessing.RoiControl.Controls
|
||||
|
||||
private void Canvas_PreviewMouseRightButtonUp(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(
|
||||
$"[ViewportMouse] RoiCanvas.PreviewMouseRightButtonUp source={e.OriginalSource?.GetType().Name}, " +
|
||||
$"handled={e.Handled}, suppress={SuppressContextMenu}");
|
||||
// BGA 模式下阻止 ContextMenu 弹出
|
||||
if (CurrentMeasureMode == Models.MeasureMode.BgaVoid && _bgaCurrent != null)
|
||||
{
|
||||
|
||||
@@ -29,8 +29,9 @@ namespace XplorePlane.Views.Main.Overlays
|
||||
|
||||
public InspectionMarkOverlay()
|
||||
{
|
||||
// 默认状态:无工具激活 → 不拦截鼠标事件,避免阻挡下层的测量拖拽/图像平移等
|
||||
IsHitTestVisible = false;
|
||||
// 背景保持 null,不拦截空白区域的鼠标事件;标记图标自身仍需可命中,
|
||||
// 这样实时预览区右键标记时可以先由标记层处理,避免落到底层 RoiCanvas 菜单。
|
||||
IsHitTestVisible = true;
|
||||
Background = null;
|
||||
MouseLeftButtonDown += OnMouseLeftButtonDown;
|
||||
MouseRightButtonDown += OnMouseRightButtonDown;
|
||||
@@ -87,11 +88,13 @@ namespace XplorePlane.Views.Main.Overlays
|
||||
private static void OnVisualStateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
var overlay = (InspectionMarkOverlay)d;
|
||||
// 仅当标记工具激活时才允许命中测试,否则 Background=Transparent 会拦截
|
||||
// 下层所有鼠标事件(测量拖拽、图像平移、ROI 编辑等)。
|
||||
bool isInteractive = !overlay.IsReadOnly && overlay.ActiveTool != InspectionMapActiveTool.None;
|
||||
overlay.IsHitTestVisible = isInteractive;
|
||||
overlay.Background = isInteractive ? Brushes.Transparent : null;
|
||||
// 背景为 null 时,空白区域继续穿透到下层;但标记图标必须保持命中,
|
||||
// 否则实时预览区的右键会直接触发 RoiCanvas 的缩放/保存菜单。
|
||||
bool canHitMarks = !overlay.IsReadOnly && overlay.ShowMarks;
|
||||
overlay.IsHitTestVisible = canHitMarks;
|
||||
overlay.Background = canHitMarks && overlay.ActiveTool != InspectionMapActiveTool.None
|
||||
? Brushes.Transparent
|
||||
: null;
|
||||
overlay.RenderMarks();
|
||||
}
|
||||
|
||||
@@ -123,6 +126,9 @@ namespace XplorePlane.Views.Main.Overlays
|
||||
icon.MouseLeave += (_, _) => icon.Opacity = 1.0;
|
||||
icon.MouseRightButtonDown += (s, e) =>
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(
|
||||
$"[ViewportMouse] Mark.MouseRightButtonDown type={mark.Type}, cncNode={mark.CncNodeId}, " +
|
||||
$"source={e.OriginalSource?.GetType().Name}, handled={e.Handled}");
|
||||
e.Handled = true;
|
||||
MarkContextMenuRequested?.Invoke(this, mark);
|
||||
};
|
||||
@@ -213,6 +219,9 @@ namespace XplorePlane.Views.Main.Overlays
|
||||
{
|
||||
var hit = Children.OfType<FrameworkElement>()
|
||||
.FirstOrDefault(c => IsNear(e.GetPosition(this), c));
|
||||
System.Diagnostics.Debug.WriteLine(
|
||||
$"[ViewportMouse] MarkOverlay.MouseRightButtonDown hit={hit?.Tag is InspectionMarkRecord}, " +
|
||||
$"source={e.OriginalSource?.GetType().Name}, handled={e.Handled}, point={e.GetPosition(this)}");
|
||||
if (hit?.Tag is InspectionMarkRecord mark)
|
||||
{
|
||||
MarkContextMenuRequested?.Invoke(this, mark);
|
||||
|
||||
@@ -328,6 +328,13 @@ namespace XplorePlane.Views.Main
|
||||
};
|
||||
_inspectionMarkOverlay.MarkContextMenuRequested += (_, mark) =>
|
||||
{
|
||||
_log.Information("[ViewportMouse] MarkContextMenuRequested markId={MarkId}, type={Type}, " +
|
||||
"status={Status}, cncNodeId={CncNodeId}, cncRunId={CncRunId}",
|
||||
mark.MarkId,
|
||||
mark.Type,
|
||||
mark.Status,
|
||||
mark.CncNodeId,
|
||||
mark.CncRunId);
|
||||
vm.SelectedMark = mark;
|
||||
ShowInspectionMarkContextMenu(mark, vm);
|
||||
};
|
||||
@@ -345,6 +352,11 @@ namespace XplorePlane.Views.Main
|
||||
|
||||
private void ShowInspectionMarkContextMenu(InspectionMarkRecord mark, ViewModels.Inspection.Documentation.InspectionMapViewModel vm)
|
||||
{
|
||||
// CNC 标记和人工标记统一使用 Mark 菜单;仅屏蔽底层 RoiCanvas 的默认菜单。
|
||||
_log.Information("[ViewportMouse] Show Mark context menu markId={MarkId}, cncNodeId={CncNodeId}",
|
||||
mark.MarkId,
|
||||
mark.CncNodeId);
|
||||
|
||||
var menu = new System.Windows.Controls.ContextMenu();
|
||||
var properties = new System.Windows.Controls.MenuItem { Header = "编辑属性" };
|
||||
properties.Click += (_, _) =>
|
||||
|
||||
@@ -233,10 +233,25 @@ namespace XplorePlane.Views.Main
|
||||
RoiCanvas.ContextMenu = menu;
|
||||
RoiCanvas.ContextMenuOpening += (s, e) =>
|
||||
{
|
||||
if (RoiCanvas.SuppressContextMenu)
|
||||
var originalSource = e.OriginalSource as System.Windows.DependencyObject;
|
||||
bool isInspectionMarkSource = _inspectionMarkOverlay != null &&
|
||||
originalSource is System.Windows.Media.Visual visual &&
|
||||
(ReferenceEquals(visual, _inspectionMarkOverlay) ||
|
||||
visual.IsDescendantOf(_inspectionMarkOverlay));
|
||||
_log.Information("[ViewportMouse] RoiCanvas.ContextMenuOpening source={Source}, original={OriginalSource}, " +
|
||||
"handled={Handled}, suppress={SuppressContextMenu}, markSource={MarkSource}, markHitTest={MarkHitTest}",
|
||||
s?.GetType().Name,
|
||||
e.OriginalSource?.GetType().Name,
|
||||
e.Handled,
|
||||
RoiCanvas.SuppressContextMenu,
|
||||
isInspectionMarkSource,
|
||||
_inspectionMarkOverlay?.IsHitTestVisible);
|
||||
if (RoiCanvas.SuppressContextMenu || isInspectionMarkSource)
|
||||
{
|
||||
RoiCanvas.SuppressContextMenu = false;
|
||||
e.Handled = true;
|
||||
_log.Information("[ViewportMouse] RoiCanvas context menu suppressed, reason={Reason}",
|
||||
isInspectionMarkSource ? "inspection-mark" : "external-request");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user