Commit Graph

887 Commits

Author SHA1 Message Date
zhengxuan.zhang c17c76e90f 修复分组设置生成检测池后下一步按钮不刷新
Pool 属性 setter 只做 SetProperty,未触发 UpdateNavigationState,
而生成检测池时 CurrentStage 赋值前后相同不会触发导航状态刷新,
导致分组变蓝后 CanGoNext 停留在旧值,下一步按钮无法点击。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-04 09:49:17 +08:00
zhengxuan.zhang 0d1cda6403 修复流水线属性面板实时预览缺失叠加显示
CncInspectionModulePipelineViewModel.ExecutePreviewAsync 只推送了结果图,
未像 PipelineEditorViewModel 一样调用 PushDetectionOverlay,
导致调参实时预览时不会叠加显示 BGA 检测的圆形标注。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-04 09:35:13 +08:00
zhengxuan.zhang e3466d03f0 优化流水线属性检查器布局 2026-08-03 17:40:08 +08:00
zhengxuan.zhang 1ccf3e094f 修复 BGA 识别后下一步状态刷新 2026-08-03 17:29:43 +08:00
zhengxuan.zhang 67487292c8 复用流水线 BGA 结果并增强圆形叠加 2026-08-03 17:25:34 +08:00
zhengxuan.zhang c57876e618 修复 BGA 识别结果绿色圆叠加显示 2026-08-03 17:06:08 +08:00
zhengxuan.zhang a96b670dd2 对齐 VS Code Light 配色令牌 2026-08-03 17:01:24 +08:00
zhengxuan.zhang 4e358220b5 调整 NOVA 浅色蓝色主题配色 2026-08-03 16:58:18 +08:00
zhengxuan.zhang 7007d94843 fix(ui): 修复主页 Ribbon 组被折叠、显示不完整的问题
现象:主页 tab 的「程序」组被折叠成下拉按钮,运行/停止/实时/开窗/关窗
不再直接可见,看起来像整组被缩放。

根因:GroupVariant 声明的是「收缩台阶」,按 Priority 从大到小尝试,且
只在该 variant 比当前尺寸更小时才生效。原有的 Priority=0 Variant=Large
实际是 no-op(Large 永远不小于当前尺寸),等于声明「本组无台阶可让」。
而「程序」组当时完全没有 Variants 声明,回落到默认的四档全循环,成了
整个 tab 里唯一能让出空间的组,宽度一紧张就被一路抽到 Collapsed。

进一步测量发现该 tab 在 1920 宽度下实际溢出仅约 10~30px,而 Collapsed
是个约 400px 的大台阶——为补 20px 的缺口牺牲整组,导致右侧空出一大块。
所以真正的修法是把这 20px 抠出来让它放得下,而不是让某个组让位。

修复分两部分:

1. 抠出约 68px 消除溢出(列宽由该列最长标签决定)
   - 测量工具:点点距测量→点点距、点线距测量→点线距、角度测量→角度、
     通孔填锡率→填锡率、气泡测量→气泡(ScreenTip 保留完整名称不变,
     悬停仍显示「通孔填锡率测量」等;组名已是「测量工具」,标签再带
     「测量」属冗余)
   - 图像算子:StackPanel 150→130、ComboBox 140→122

2. 补真实的让位梯度替代 no-op 声明,作为窄屏/高 DPI 下的兜底
   快捷工具(60) → 图像算子(50) → 测量工具(40) → 文件(30) →
   高级模块(20) → CNC(10) → 程序(1)
   「程序」给 Priority=1 而非完全钉死:若七组都不让位,超宽时 Telerik
   会直接裁掉右边而非折叠,退化成「内容被切掉」比「变下拉按钮」更糟。
   1920 下这些台阶均不触发,外观与全 Large 一致。

顺带:每组补 Icon(折叠态下拉按钮此前无图标可显示);「文件」组的
ScreenTip.Title 从抄漏的 "Clipboard" 改为「文件」。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-03 16:50:41 +08:00
zhengxuan.zhang ff5a314e61 feat(inspection): 矩阵池BGA圆检测接入主界面实时预览
- Stage2 圆检测改为调用真实 BgaDetectionEngineService(取主视口图像转16位灰度),不再默认使用模拟数据
- 新增 BgaBallGroupLabeler,按行列聚类复用 BgaGridGeometry/BgaTargetIdGenerator 生成 A1-D4 分组编号
- 打通 ITaskWizardOverlayService.OverlayChanged 发布/订阅链路:ViewportPanelView 订阅该事件,
  通过新增的 WizardOverlayRenderer 在主预览画布上渲染绿色圆+分组编号(以及 Block 网格/校准标记/扫描进度)
- PolygonRoiCanvas 新增 SetWizardOverlayCanvas/ClearWizardOverlay,与现有检测层/检测池层独立管理

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-03 15:46:04 +08:00
zhengxuan.zhang 9dad748906 fix(ui): 收敛 NavToolButtonStyle/DisplayValueLabel 遗留高度值
Task#2 数值收敛验证补漏,修复两处未被原扫描脚本覆盖的 Style-Setter
级 Height 字面值:

- NavigationPropertyPanelView.xaml:NavToolButtonStyle 为 23×22(宽高不
  等,不满足方形图标按钮豁免),Height=22 属于文档收敛范围
  {22,28,30,32,40},改为 NovaButtonHeightSm
- CncPageView.xaml:DisplayValueLabel(只读展示态 Label,与同一表单网
  格内的 EditorBox TextBox 并列)Height=28 属于输入框收敛范围
  {28,30,36},改为 NovaInputHeightSm,与相邻输入框高度对齐

OperatorToolboxView.xaml 的 CompactIconButtonStyle(22×22,宽高相等)
维持豁免不动,符合既定的方形图标按钮豁免规则。

复扫结果:tag 级 Height/Width、Style-Setter 级 Height、注释外裸十六
进制色、StaticResource 引用完整性四类检查全部归零。
2026-08-03 11:33:19 +08:00
zhengxuan.zhang d8abae0c63 fix(ui): 修复「图像算子」Ribbon 组被折叠不展开的问题
根因:「图像算子」RadRibbonGroup 缺少 GroupVariant 声明,而旁边的 CNC、
高级模块、测量工具等组都设了 Priority=0 Variant=Large(强制保持 Large
不折叠)。Telerik Ribbon 空间不足时优先折叠没有 Variants 声明的组,
因此「图像算子」被第一个牺牲——表现为 Large 按钮被压缩成 Collapsed 状态
的小图标,看起来像图标没展开。

修复:
- 给「图像算子」组加上 GroupVariant Priority=0 Variant=Large
- 顺带给「快捷工具」组也加上同样声明(一致性,避免窗口变窄时该组也被折叠)

这与上一个 commit(补 LargeImage)是两个独立问题:
- LargeImage 缺失 → 图标区域只显示 16px 小图(已修)
- GroupVariant 缺失 → 整个组被折叠成 Collapsed 状态(本次修)
2026-08-01 13:47:34 +08:00
zhengxuan.zhang 610daf5e24 fix(ui): 修复 Ribbon Large 按钮图标未展开显示的问题
所有 Size=Large 的 RadRibbonButton 此前只设了 SmallImage(16×16),
未设 LargeImage。Telerik Windows11 主题下 Large 模式要求 LargeImage
(32×32 占位);缺失时图标区域保持 32px 占位但只画 16px 小图,
导致按钮整体高度被挤压、文字显示不全(截图表现为图标和文字被压缩)。

修复:为 MainWindow.xaml 中全部 21 个 Large 按钮补上 LargeImage 属性,
暂时指向与 SmallImage 相同的 PNG(16px 放大到 32px 区域,布局恢复正常)。
后续可制作 32×32 版本图标进一步优化清晰度。
2026-08-01 13:44:00 +08:00
zhengxuan.zhang 7ffde4e08f refactor(ui): 其余 30 个文件全量令牌化(237 处)
Hardware/Main/Setting/Debug/Help/Cnc 等剩余 30 个 XAML 文件中全部可迁移的
裸 HEX 颜色替换为 Nova 令牌引用。全应用残留从 249 处降至 12 处。

残留的 12 处均为明确保留项(不在 NOVA 映射范围):
- SplashScreen 独立样式(启动画面进度条 2 处)
- ViewportPanelView 棋盘格纹理 + 半透明白底(4 处)
- MainWindow/MarkPropertiesWindow 半透明白色叠加层(3 处)
- NavigationPropertyPanelView 纯黑文字(1 处)
- OperatorToolboxWindow DropShadowEffect 色值(1 处)
- SettingsWindow XML 注释内(1 处)

覆盖的主要模块:
- Hardware:AxisControlPanel(39) / MotionControl(18) / RaySource(10) / Detector(4)
- Main:MainWindow(17) / ViewportPanel(11) / NavigationPropertyPanel(21) /
  RecordingToolbar(5) / RibbonStatusArea(1) / NavigationPanel(5)
- Setting:SettingsWindow(23) / RecordingSetup(3) / Login(2)
- Debug:DebugPanel(8) / DebugMotionToolbar(3) / SnapshotViewer(2) /
  SnapshotManager(1) / PerformanceMonitor(1) / StateDisplay(1)
- Help:LibraryVersions(6)
- Cnc:InspectionReportViewer(27) / InspectionReview(6) / MarkProperties(12) /
  TemplateMatchAlignment(10) / TemplateMatchAssistant(3)
- ImageProcessing:PipelineEditorWindow(3) / OperatorToolboxWindow(2) / ImagePanel(3)

字号收敛:FontSize=13 → NovaFontSizeBody;密集面板保留现状
圆角收敛:CornerRadius=6 → NovaRadiusSm(8)、3 → NovaRadiusXs(4)
2026-08-01 13:33:42 +08:00
zhengxuan.zhang 827cf17e8b refactor(ui): 检测面板 + MeasurementStatsView 全量令牌化(82 处)
7 个检测面板(BgaDetectionPanel / BubbleMeasurePanel / EdgeCircleFitPanel /
EdgeLineFitPanel / QfnLeadPadDetectionPanel / VoidDetectionPanel /
CameraSettingsWindow)和 MeasurementStatsView 中全部裸 HEX 颜色替换为
Nova 令牌引用,8 个文件残留均归零。

通用灰阶
- 窗口/面板背景 #F5F5F5 → NovaSurfaceBrush
- 卡片/DataGrid 边框 #E8E8E8 → NovaOutlineVariant
- 输入框/中等边框 #D0D0D0/#cdcbcb → NovaOutline
- DataGrid 表头/浅底 #FAFBFC/#F8F9FA → NovaSurfaceContainerLow
- 只读输入框 #F0F0F0 → NovaSurfaceContainerLow
- 主文字 #333 → NovaOnSurface
- 次要文字 #555/#666/#888 → NovaOnSurfaceVariant
- 弱边框 #EEE → NovaOutlineVariant

DataGrid 条件行背景
- 失败行 #FFF0F0 → NovaErrorContainer
- 信息行 #EDF4FC → NovaInfoContainer

MeasurementStatsView
- Pass 计数 #2E7D32 → NovaSuccess
- Fail 计数 #C62828 → NovaError
- 本地资源已在前序阶段令牌化,本次处理行内残留

字号
- FontSize=13 → NovaFontSizeBody;密集面板 11/11.5/10/12 保留
- FontSize=20(统计大数字)→ NovaFontSizeSubtitle(18)
2026-08-01 11:21:27 +08:00
zhengxuan.zhang 5ad0110636 refactor(ui): MatrixPageView 全量令牌化(66 处)
矩阵编排页面中全部裸 HEX 颜色替换为 Nova 令牌引用,残留归零。

本地资源定义(9 个)
- PageBg/PanelBorder/Ink/InkSub/TaughtGreen/TaughtGreenSoft/
  CurrentOrange/CurrentOrangeSoft/RunGreen 的 Color 全部改为引用
  NovaColors.xaml 令牌

矩阵单元格执行状态色
- Executing → InfoBrush + PrimaryBrush(蓝色系,与 CncPageView 一致)
- Completed → SuccessBrush + OnSuccessContainerBrush
- Error → ErrorBrush + OnErrorContainerBrush
- Disabled → SurfaceDim + OnSurfaceVariant

其余
- 停止按钮 → ErrorContainerBrush/OnErrorContainerBrush
- 运行按钮 → RunGreen(SuccessColor) / 悬停 SuccessBrush / 禁用 OnBackgroundDisabled
- 禁用按钮底 #B9C4D6 / 运行非激活 #AFC8B7 → OnBackgroundDisabled
- 网格边框/面板背景/表头底色统一收敛
- FontSize=13 收敛为 NovaFontSizeBody;密集面板字号保留现状
- CornerRadius=6 收敛为 NovaRadiusSm(8);圆形徽标 9 和底部半圆角保留
2026-08-01 10:56:40 +08:00
zhengxuan.zhang 70fd137e90 refactor(ui): 流水线编辑三件套全量令牌化(114 处)
PipelineEditorView / OperatorToolboxView / ImageProcessingPanelView 中
全部裸 HEX 颜色替换为 Nova 令牌引用,三个文件残留均归零。

PipelineEditorView(80 处)
- 本地资源(PanelBg/PanelBorder/SeparatorBrush/AccentBlue/DisabledNode*)
  已在前序阶段改为引用 Nova Color 令牌
- 节点状态色全部映射:执行终止→Success、跳过→SurfaceLow/OutlineVariant、
  禁用+选中→SecondaryContainer/Info
- ToggleButton 实时生效:关态→OutlineVariant/Outline、开态→Success/
  OnSuccessContainer、悬停→SurfaceContainerHighest
- ROI 面板:信息底→InfoContainer/Info/Primary、警告→WarningContainer/
  Warning/OnWarningContainer、操作按钮→Primary/Success/Error
- 参数 Slider 范围标签/验证错误→OnSurfaceVariant/Error

OperatorToolboxView(24 处)
- 本地资源已在前序阶段处理
- TabItem 选中态边框→NovaInfoBrush(前序残留已清)
- 标题栏→NovaPrimary、关闭按钮悬停→Error
- 搜索框/列表边框/空状态面板统一走 Nova 令牌
- 添加按钮「+」图标色→InfoBrush

ImageProcessingPanelView(10 处)
- 本地资源已在前序阶段处理
- GroupBox 隐式样式的前景/边框→OnSurface/Outline
- 状态栏文字→OnSurface
- 密集面板字号保留现状
2026-08-01 10:18:01 +08:00
zhengxuan.zhang 680c5840b6 refactor(ui): CncPageView + CncEditorWindow 全量令牌化(68 处)
CNC 编辑器主界面(密集面板)和编辑器窗口中全部裸 HEX 颜色替换为
Nova 令牌引用,残留归零。

CncPageView(64 处)
- 5 个本地 SolidColorBrush 资源的 Color 改为引用 Nova 令牌
  (PanelBg/PanelBorder/SeparatorBrush/HeaderBg/TreeChildLineBrush)
- 节点树触发器中的执行状态色(Running→Warning、Succeeded→Success、
  Failed→Error、InsertAnchorAbove→Info/SecondaryContainer、
  InsertAnchorBelow→Warning)全部映射到 NOVA 语义色
- 密集面板字号保留现状(11/10/10.5/12 不动),仅 FontSize=13 收敛为
  NovaFontSizeBody(14)
- CornerRadius=6 收敛为 NovaRadiusSm(8)

CncEditorWindow(4 处)
- 运行状态底栏的背景/边框/文字前景/错误态文字
2026-08-01 10:01:39 +08:00
zhengxuan.zhang 59c1707393 refactor(ui): InspectionTaskWizardWindow 全量令牌化(107 处)
检测任务向导 9 阶段模板中全部裸 HEX 颜色和越界字号替换为 Nova 令牌引用,
残留归零。这是 P3 逐页迁移的第一个文件,也是单文件改动量最大的一个。

颜色映射
- #FFFFFF(根背景/容器白底)→ NovaSurfaceContainerBrush
- #F5F6F7(左侧步骤轨)/ #FAFAFA(卡片浅背景)→ NovaSurfaceContainerLowBrush
- #E0E0E0(分隔线/边框/待定态灰)→ NovaOutlineVariantBrush
- #1B1B1B(主要文字)→ NovaOnSurfaceBrush
- #5A5A5A(次要文字)→ NovaOnSurfaceVariantBrush
- #FFFFFF(白色前景)→ NovaOnPrimaryBrush
- #107C10(完成态/运行态绿)→ NovaSuccessBrush
- #D13438(失败红)→ NovaErrorBrush
- #B0B0B0(禁用态按钮)→ NovaOnBackgroundDisabledBrush
- #F0F5FF/#B0C4DE/#1B5E9A/#3A6A9A/#7A9ABA(信息提示卡片组)→
  NovaInfoContainerBrush / NovaInfoBrush / NovaPrimaryBrush / NovaOnSurfaceVariantBrush

字号收敛
- FontSize="13" → NovaFontSizeBody (14):全部替换
- FontSize="14" → NovaFontSizeBody (14):统一引用令牌
- FontSize="16" → NovaFontSizeBodyStrong (16):标题
- FontSize="12" → NovaFontSizeCaption (12):说明文字
- FontSize="20" → NovaFontSizeSubtitle (18):判定结果大标题
- FontSize="11" → 保留现状(步骤数字,密集面板例外)
2026-07-31 17:29:58 +08:00
zhengxuan.zhang 8a41af3e38 refactor(ui): 统一焦点可见性样式,修补两处缺口
排查 NovaControls.xaml 里全部 14 个具名样式的 FocusVisualStyle 设置情况,
发现两处与文件头「工业上位机键盘/戴手套操作场景,焦点必须可见」的既定
原则矛盾:

- NovaListBoxItem 把 FocusVisualStyle 显式置空,且没有替代方案说明。
  键盘方向键切换项时 IsSelected 会变但不总与焦点同步(如多选场景),
  仅靠选中态背景不足以替代明确的焦点环。改为引用 NovaFocusVisualStyle
- NovaComboBoxItem 完全未设置该属性,走 WPF 默认虚线框,与其余控件的
  Nova 描边风格不一致。补充引用 NovaFocusVisualStyle

未改动 NovaTextBox:它刻意置空 FocusVisualStyle,焦点态改用 Chrome 的
BorderBrush/BorderThickness 变化表达(IsKeyboardFocused 触发器),
文件内已有注释说明「再叠加默认虚线框会显得杂乱」,这是合理设计,不是缺口。

其余 12 个样式此前已设置,未改动。

验证
- 反射枚举资源字典中全部 Nova* 样式,逐一核对 FocusVisualStyle:
  9 个直接控件实例化后 FocusVisualStyle 均非空(含通过 BasedOn 继承拿到
  的 4 个按钮变体——style.Setters 只含自身声明的 Setter,不含继承链,
  因此改用真实实例判定而非静态枚举)
- NovaTextBox 单独验证描边路径:Focus() 后边框厚度从 1 变为 2、边框色
  变为 NovaPrimaryColor,确认焦点提示实际生效
2026-07-31 17:11:13 +08:00
zhengxuan.zhang bb2c9bb8aa refactor(ui): C# 侧判定色统一为 NOVA 语义色,删除重复死代码
排查发现全应用存在两套判定色实现:Converters.cs 中三个转换器
(PassFailColorConverter/RunStatusColorConverter/EventTypeIconConverter)
实际被 XAML 绑定使用;而 InspectionRunRowViewModel.PassLabelColor/
StatusWarningColor、InspectionRunEventRowViewModel.IconColor、
InspectionNodeCardViewModel.PassLabelColor 四处同名同义属性硬编码了
几乎相同的色值(#2E7D32/#C62828/#E65100/#1565C0/#9E9E9E 等),但逐一核对
全部 XAML 后确认这四处从未被任何 Binding 引用——是死代码。

新增 Themes/NovaResourceHelper.cs
- FindBrush(key):从 Application.Resources 按键取 Nova 令牌画刷,供
  ViewModel/Converter 等无法用 XAML StaticResource 表达的纯代码路径使用
  (例如 switch 表达式按枚举选择画刷)
- 不是运行时主题切换机制,项目不做深色模式;目的是让代码侧判定色与
  XAML 侧共用 NovaColors.xaml 同一份定义,不在代码里重复写 hex

Converters.cs 三个实际生效的转换器改用 Nova 令牌
- PassFailColorConverter: NovaSuccessBrush / NovaErrorBrush
- RunStatusColorConverter: NovaErrorBrush / NovaWarningBrush
- EventTypeIconConverter: NovaInfoBrush / NovaSuccessBrush / NovaErrorBrush /
  NovaWarningBrush / NovaOnSurfaceVariantBrush

InspectionMetricRowViewModel.RowBackground(唯一在用的 VM 计算属性颜色)
- 原硬编码 #E8F5E9/#FFEBEE 改为 NovaSuccessContainerBrush/NovaErrorContainerBrush

删除四处死代码
- InspectionRunRowViewModel.PassLabelColor / StatusWarningColor
- InspectionRunEventRowViewModel.IconColor
- InspectionNodeCardViewModel.PassLabelColor
均保留代码注释说明原属性的历史用途与实际生效路径,便于后续排查时
理解为何被删除而非误判为遗漏

未处理范围
- Models/Main/Models.cs 的 NavLeafNode.IconColor 默认参数 "#888888":
  该类未被任何代码实例化(连同 NavGroupNode/InspectionCalloutVM 等整个
  文件均为死代码),不在本次判定色范围内,保持原样
- XP.ReportEngine 的颜色配置(模板字体色、条件颜色规则)属跨模块业务配置
  而非 UI 判定色,不在本次范围

验证
- 独立测试宿主实测四个转换后的取色路径:PassFailColorConverter/
  RunStatusColorConverter/EventTypeIconConverter 各分支色值,以及
  RowBackground 的 IsPass=true/false 两种取值,均与 NovaColors.xaml
  中对应令牌一致;null/未匹配枚举值的 Transparent 兜底路径同样验证通过
2026-07-31 17:02:12 +08:00
zhengxuan.zhang 37cfc95d97 refactor(ui): 统一主色与浅强调底为 NOVA 语义色
全应用此前存在 5 种主色(#0F6CBD/#005FB8/#0078D4/#2F6FE0/#1F5AC4)和
5 种浅蓝强调底(#EAF2FB/#EAF1FE/#E3F0FF/#F5F9FF/#D9ECFF),互不一致。
现统一收敛到 NovaPrimaryBrush/NovaPrimaryContainerBrush(主色)与
NovaSecondaryContainerBrush(浅强调底)。

主色 → NovaPrimaryBrush / NovaPrimaryContainerBrush
- MainWindow:Ribbon 选中态、按下态(3 组 Setter + 1 个自定义模板 Border,
  共 10 处 #0F6CBD/#0D5BA8)
- InspectionTaskWizardWindow:左侧步骤轨指示条、步骤徽标、按钮背景
  (10 处 #0F6CBD)
- EdgeCircleFitPanel/EdgeLineFitPanel:拟合按钮文字强调色(各 1 处 #005FB8)
- NavigationPropertyPanelView:像素坐标文字强调色(1 处 #0078D4)
- MatrixPageView:本地资源 Accent/AccentDark 的 Color 改为指向
  NovaPrimaryColor/NovaPrimaryContainerColor,保留资源名不改下游引用

浅强调底 → NovaSecondaryContainerBrush
- MeasurementStatsView/PipelineEditorView/OperatorToolboxView:本地资源
  AccentBlue/SelectedTabBg 的 Color 改为指向 NovaSecondaryContainerColor
- MatrixPageView:AccentSoft 改为指向 NovaSecondaryContainerColor
- PipelineEditorView:算子节点选中态背景直接引用改为
  NovaSecondaryContainerBrush(此前是独立硬编码 #D9ECFF,未走本地资源)

其余按钮实现细节保持不变(disabled 色 #B0B0B0/#B9C4D6、hover 态等),
仅替换主色/强调底本身,缩小改动面。

验证
- 实测 MatrixPageView:本地资源在 UserControl.Resources 中定义、
  Color 引用 Application.Resources 里 NovaColors.xaml 令牌的写法能正确
  解析(Accent=#FF005198、AccentDark=#FF00284C、AccentSoft=#FFE6EAF0,
  与预期一致)。这与 Generic.xaml 主题字典的解析路径不同(后者需要显式
  合并),此处走的是普通逻辑树查找,无需额外处理
- MeasurementStatsView/OperatorToolboxView/PipelineEditorView 因 Prism
  自动装配 ViewModel 需要 DI 容器,测试宿主中抛出构造异常,与本次颜色
  改动无关;实际运行由 App 容器提供 ViewModel,路径不受影响
2026-07-31 16:52:31 +08:00
zhengxuan.zhang 3a2de0e1e0 refactor(ui): 7 个检测面板统一改用共享图标按钮样式
BgaDetectionPanel、BubbleMeasurePanel、EdgeCircleFitPanel、EdgeLineFitPanel、
QfnLeadPadDetectionPanel、VoidDetectionPanel 此前各自定义了完全相同的本地
样式 IconBtnStyle(TargetType="ButtonBase",白底浅灰描边,悬停浅蓝,勾选深蓝),
6 份复制、硬编码 #EAF2FB/#B0D4F1/#005FB8/#004C99 等共 24 处色值。
CameraSettingsWindow 另有两个内联的等价按钮样式(深蓝主操作 + 浅蓝次操作)。

新增 NovaControls.xaml 中的 NovaIconButton,6 个面板改为引用该样式并删除
本地定义;CameraSettingsWindow 的两个内联按钮改为引用 NovaButtonPrimary /
NovaButtonSecondary。

TargetType 用 ButtonBase(Button/ToggleButton/RadioButton 的公共基类),
一份样式覆盖工具栏里 Button(执行/清除)、ToggleButton(启用 ROI)、
RadioButton(工具切换)三种控件,与原 IconBtnStyle 的适用范围一致。

配色改动说明
- 默认底/描边 → surfaceContainer/outlineVariant
- 悬停 #EAF2FB/#B0D4F1(浅蓝)→ NovaSurfaceHoverBrush(surface+16%黑叠加),
  与 NovaButtonSecondary/Tertiary 的悬停算法一致。视觉上从浅蓝调变为浅灰调,
  这是遵循 NOVA 状态层算法一致性的主动选择,NOVA 色板没有对应的浅蓝语义令牌
- 选中/勾选 #005FB8/#004C99(深蓝)→ NovaPrimaryBrush/NovaPrimaryContainerBrush,
  语义对应更准确(选中态 = 强调态)

验证
- 实测 NovaIconButton 套用在纯 Button 上不抛异常:DataTrigger 绑定
  RelativeSource Self 的 IsChecked,在没有该依赖属性的 Button 上会静默
  不生效而非报错,与原实现行为一致
- ToggleButton/RadioButton 的勾选/选中态背景色实测正确切换
- 卡片、标签、DataGrid 等本地样式的裸 HEX 不在本次范围,各面板仍有
  3~10 处残留,留待后续迭代
2026-07-31 16:30:12 +08:00
zhengxuan.zhang b98b06adbb feat(ui): 新增 NovaControls.xaml 共享控件样式库
P3 逐页迁移的载体:Button 四变体 + Ghost、TextBox、ComboBox、CheckBox、
RadioButton、ListBoxItem 的带 Key 样式,页面迁移时改为引用这里的 Key,
不再各自定义局部样式或硬编码 HEX。

按钮
- Primary / Secondary / Tertiary / Danger 各自一份 ControlTemplate,
  Hover/Pressed 触发器直接引用对应变体的预合成画刷
- Ghost(纯文本按钮)单独模板:无背景无边框,Hover 加下划线
- 曾尝试单一模板 + Tag 传参共享(数组或索引器绑定),实测
  ControlTemplate.Triggers 里的 Setter 通过该方式取值时行为不稳定:
  Hover/Pressed 不生效,且个别变体在 x:ArrayExtension 场景下于资源加载
  阶段抛 DeferredAppResourceReference 空引用异常。改为逐变体复制模板,
  公共部分(尺寸/字体/圆角/禁用态/焦点样式)仍抽到 NovaButtonBase 共享

输入类控件
- TextBox:焦点态改变描边色与厚度承担焦点可见性职责,禁用/只读/校验错误
  各有独立触发器
- ComboBox:仅统一颜色与圆角,未重做下拉箭头细节(已在文件头注明缺口)
- CheckBox/RadioButton:方框/圆框 + 选中态图形,结构一致仅形状不同
- ListBoxItem:选中态与「选中+悬停」的多条件叠加态

首次启用此前从未被引用的三个令牌
- NovaFocusThickness / NovaStateFocusPrimaryBrush:统一焦点可见性样式
  NovaFocusVisualStyle,工业上位机的键盘/戴手套操作场景需要
- NovaDisabledOpacity:所有交互控件禁用态统一淡化,不逐变体定义禁用色组合

NovaColors.xaml 补全
- 新增按钮交互态预合成色(Primary/Danger 的 Hover、Surface 的 Hover/Press),
  算法与 NovaPalette.cs 的 Composite 方法一致(source-over),用独立脚本
  精确核算,过程中订正了一处手算错字(Danger Hover 多算入 1)
- 补上此前遗漏的 NovaStatePressOnPrimaryColor(对应 CSS 源
  sys-stateLayers-pressOnPrimary)
- 系统性排查并补全此前「Color 有定义、Brush 未生成」的缺口:
  NovaOnErrorBrush 等 8 个画刷。此缺口是本次调试中真实触发的产品缺陷
  (NovaButtonDanger 因 NovaOnErrorBrush 缺失而抛
  InvalidOperationException),已用测试固化验证覆盖所有触发器引用的
  画刷键,防止同类问题再次出现

验证
- 全部样式已实例化验证:默认外观取值、CheckBox/RadioButton 选中态图形
  可见性、ListBoxItem 选中态背景、ComboBox 模板套用均通过
- 调试过程中发现一个测试环境陷阱:无 Application.Run() 消息循环时,
  Window.Close() 后立即创建下一个窗口会导致后续样式解析异常/静默失败,
  与产品代码无关,已在验证脚本中记录规避方式
2026-07-31 16:17:30 +08:00
zhengxuan.zhang e58e0b1cf6 refactor(ui): 自定义控件默认样式接入 NOVA 令牌
Generic.xaml 是 AnimatedSwitch 与 ZoomableImageViewer 的默认样式,全应用共用,
改一处即覆盖所有使用点。原有 6 个裸 HEX 全部消除。

色值映射
- AnimatedSwitch 轨道描边 #C9D1D8 → NovaOutline(NOVA 将输入框类描边归为 outline)
- AnimatedSwitch 关态轨道 #D5DCE3 → surfaceContainerHighest
- AnimatedSwitch 开态轨道 #2DCC70 → NovaSuccess。刻意保留绿色语义
  (工业场景 绿=使能/运行),而非改为平台惯例的 primary
- ZoomableImageViewer 背景 #F5F5F5 → surfaceContainerLow
- 占位块 #E0E0E0 → surfaceContainerHighest
- 占位文字 #757575 → onSurfaceVariant,字号改为引用 NovaFontSizeBody

两个实现约束(均由实测确认)
- 必须在 Generic.xaml 内显式合并 NOVA 字典:主题字典的 StaticResource 在字典
  加载时解析,作用域仅本字典及其 MergedDictionaries,不会回退到
  Application.Resources
- 合并源必须用带 ;component 的完整 pack URI。相对形式 /Themes/... 会解析到
  「入口程序集」而非本程序集,宿主不是 XplorePlane 时直接抛异常,且失败点在
  控件首次实例化,排查成本高
- 关态轨道仍保留独立 SolidColorBrush 实例而非共享资源画刷:ColorAnimation 会
  直接修改该画刷的 Color,共享资源会被连带改动,且冻结画刷无法被动画修改

验证
- 在 Application.Resources 为空的前提下实例化两个控件并套用模板,确认令牌解析
  成功、取值与预期一致,证明 Generic.xaml 的合并可独立生效
2026-07-31 15:42:40 +08:00
zhengxuan.zhang 8e9b55459c refactor(ui): 原生 WPF 面统一使用 NOVA 字体令牌
此前字体只有 Telerik 面通过调色板生效,原生面仍是雅黑或系统默认,
接入嵌入字体后反而出现字体分裂。本次收口。

清理散落的字体设置(共 101 处,三种写法)
- FontFamily="..." 属性形式 78 处:删除,交给继承与默认值接管
- <Setter Property="FontFamily" Value="..." /> 22 处:改为引用 NovaFontFamily
- TextBlock.FontFamily="..." 附加属性形式 1 处:删除
- 删除 6 个文件中各自重复定义的 UiFont / CsdFont 资源
- NavigationPropertyPanelView 的 Segoe UI 一并令牌化
- Consolas 6 处改为引用 NovaFontFamilyMono
- 保留 SplashScreen 的 Arial(启动最早期、独立线程)与
  PipelineEditorView 的 Segoe MDL2 Assets(图标字体)

在 26 个 Window 根元素上显式赋值 FontFamily
- WPF 的可继承属性只传递「被赋值」的值,OverrideMetadata 改的是默认值,
  默认值不向下继承;实测裸 Window 拿到令牌字体但其中的 Button 没有
- 隐式样式亦不可行:Style TargetType="Window" 只匹配精确类型,
  不匹配 MainWindow 等派生窗口
- 因此根元素必须携带显式值,再由继承覆盖整个窗口内容

新增 NovaPalette.ApplyDefaultFontFamily()
- 改写 Window 与 TextBlock 的字体默认元数据,覆盖不参与窗口继承的场景
  (如 Tooltip / Popup 等独立可视树)
- 不能改写 typeof(TextElement):它是该属性的注册者
- 不能改写 typeof(Control):Control 静态构造函数自身会 AddOwner,
  抢先占位会导致所有控件无法实例化(实测抛 ArgumentException)
- 各所有者类型独立 try,单点失败不影响其余;App.OnStartup 记录生效数量

验证
- 实测嵌入字形命中,LibraryVersionsWindow 内子控件正确继承到方正黑体
- 加载被改动的视图确认删除 UiFont/CsdFont 后无残留 StaticResource 解析失败
  (该类错误只在运行时抛出,编译期发现不了)
2026-07-31 15:34:42 +08:00
zhengxuan.zhang d6d8f08ac2 feat(ui): 嵌入方正黑体简体并接入 NOVA 字体令牌
字体嵌入
- 新增 Resources/Fonts/方正黑体简体.ttf,由 csproj 的 Resource glob 编译进
  程序集,已确认落入 XplorePlane.g.resources
- NovaTypography.xaml 的 NovaFontFamily 指向嵌入字体,保留
  Microsoft YaHei UI / Segoe UI 回退链

两处实测修正
- '#' 后须为字体内部家族名 FZHei-B01S,而非文件名「方正黑体简体」
- 路径须为相对形式 ../Resources/Fonts/(本文件位于 Themes/ 子目录)。
  实测前导斜杠 /Resources/Fonts/ 与两种绝对 pack URI 形式均不命中

字重调整
- 该字体提供 Normal 与 Bold 两个真字重,不存在合成加粗问题;因无 600 档,
  NovaFontWeightEmphasis 由 SemiBold 改为 Bold,避免经 WPF 匹配绕一圈。
  强调层级因此只有常规/加粗两级,第三级应改用颜色或字号表达

静默回退防护
- NovaPalette 新增 EmbeddedFontResolved:枚举字形核对家族名,确认是否真正
  解析到嵌入字体。pack URI 写错不会抛异常,此标志是唯一暴露手段
- App.OnStartup 在未命中时记 Warning 并给出检查点提示
2026-07-31 15:16:55 +08:00
zhengxuan.zhang 33cde43a6b feat(ui): 建立 NOVA 设计令牌层并统一 Telerik 调色板
设计令牌层(原生 WPF 面)
- 新增 Themes/NovaColors.xaml:NOVA v1.5 浅色语义色板,作为全应用唯一 hex
  色值来源;Brush 资源全部由 Color 资源派生,不重复写色值
- 新增 Themes/NovaMetrics.xaml:间距、圆角、组件尺寸与 elevation
  (WPF 单层 DropShadowEffect 近似 NOVA 的双层 box-shadow)
- 新增 Themes/NovaTypography.xaml:字体族、密集态字号阶梯与 7 个 TextBlock
  样式;每一档均为 NOVA 阶梯上真实存在的档位,未自造数值
- App.xaml 按 颜色 → 度量 → 排版 顺序合并三个字典;全部资源带 x:Key、
  不含隐式样式,因此合并本身不改变现有界面外观

Telerik 面统一
- 新增 Themes/NovaPalette.cs:读取上述 Color 资源写入 Windows11Palette,
  使 Ribbon / GridView / TreeView 等 Telerik 控件与原生面同源取色。
  半透明状态层按 source-over 合成为实色;关闭 UseSystemAccentColor,
  避免系统强调色覆盖 NOVA 主色
- App.OnStartup 在 Serilog 就绪后、SplashScreen 创建之前应用调色板,
  失败仅记日志不中断启动
- 刻意不设置 Telerik 基准字号,避免连带改变 Ribbon 行高与整体高度

字体嵌入准备
- csproj 增加 Resources\Fonts 下 ttf/otf 的 Resource glob;字体文件到位后
  只需替换 NovaTypography.xaml 中 NovaFontFamily 一行即可全应用生效
2026-07-31 14:05:21 +08:00
zhengxuan.zhang 272cbe20f5 feat(检测池): 向导产出可插入 CNC 的检测项目并输出兼容结果文本
检测项目产出与 CNC 打通
- 新增 PoolTaskDefinitionMapper,将 PoolTaskPlan 映射为等价的
  InspectionDefinition(Kind=Bga),内容维度对标传统 Inspection.xml:
  设备位姿、采集参数、BGA 阵列、Tile 几何与判定阈值
- 一个 Block 映射为一个 Tile,全局阵列取池行列数 × 单 Block 焊球行列数,
  保证所有 Tile 恰好构成阵列的一次划分,满足检测项目校验
- 向导 Stage 8 保存时在 PoolPlans 之外追加写入 InspectionPool 目录,
  界面提示阵列规模、Tile 数量与可插入 CNC 状态
- JsonRepositoryBase 新增 ShouldLoad 过滤钩子,
  JsonInspectionDefinitionRepository 据此跳过误放入的 PoolTaskPlan 文件,
  避免插入对话框出现无效条目

检测结果文本输出
- 新增 InspectionResultTextReporter,按 BGA_Inspection_Results.txt 的
  三段式生成逐球结果文本,逐球顺序遵循 Tile 执行顺序,
  未测得指标输出 0.00,Infinity/NaN 按原义保留
- InspectionExecutionRecorder 与 PoolArchiveHelper 追加
  inspection_results.txt 归档资产,权威数据仍为 SQLite 与 manifest.json

缺陷修复
- InspectionDecisionEvaluator.Apply 重建结果时未透传 BallResults 与
  Summary,导致判定后逐球明细与汇总统计被清空,归档结果表为空

其他
- 更新检测池任务整改文档,补充整改结果与未覆盖项说明
2026-07-31 13:07:31 +08:00
zhengxuan.zhang 95c3f08f83 feat(inspection): add self-contained xppool v2 format 2026-07-30 18:21:56 +08:00
zhengxuan.zhang 1203e41828 merge: 解决 XP.Calibration 冲突 2026-07-30 09:01:00 +08:00
zhengxuan.zhang 4342ce93a4 修复检测池的流水线 2026-07-30 08:56:39 +08:00
QI Mingxuan 1bafdbe492 已合并 PR 212: 坐标系补偿功能合并开发分支 2026-07-29 22:23:34 +08:00
zhengxuan.zhang 82de9bbf7d feat: BGA空洞率 RoiMode=None 添加全图检测日志 2026-07-29 11:47:19 +08:00
zhengxuan.zhang f98cee399e fix: 流水线处理结果被探测器实时帧覆盖 2026-07-29 11:43:54 +08:00
zhengxuan.zhang 17cb018482 feat: 流水线编辑器回调 + Stage 2 流水线可视化 2026-07-29 11:34:38 +08:00
zhengxuan.zhang 12e8818506 feat: Stage 1 新增流水线算子快照(PipelineSnapshot) 2026-07-29 11:28:04 +08:00
zhengxuan.zhang 1c6cf780ef fix: MachineParameters 属性名修正(StageXmm/StageYmm/FodMm 等) 2026-07-29 11:24:34 +08:00
zhengxuan.zhang 03d3cbaf2e fix: 添加 using XplorePlane.Services.Inspection + 修正 AcquisitionParameters 构造参数 2026-07-29 11:23:27 +08:00
zhengxuan.zhang 6a0351006b feat: Stage 1 图像调试接入 IInspectionTeachInService 捕获硬件参数 2026-07-29 11:21:25 +08:00
TANG Haowei f2ddb6a4d6 Merged PR 210: 标定箱和扫描界面支持中英文切换
1.标定箱支持中英文切换
2.扫描界面支持中英文切换
2026-07-29 07:30:27 +08:00
QI Mingxuan 41e056f85c [XP.Hardware.MotionControl] 新增 CoordinateCompensation.md:完整描述载物台坐标系补偿功能(坐标模型、像素到 mm 换算、Replace/Accumulate 记录模式与示例、接口说明、调用流程、边界注意事项、源码位置)
[XP.Hardware.MotionControl] README 文档目录树补齐全部文档条目并加入 CoordinateCompensation.md
2026-07-28 18:58:22 +08:00
Tanghaowei 31b63fd0e8 #T:修复扫描界面编码问题。 2026-07-28 18:06:13 +08:00
Tanghaowei 73d20c6930 #T:修补扫描界面xaml文件编码问题; 2026-07-28 17:45:09 +08:00
zhengxuan.zhang 1d6b47bc34 feat: BGA 识别阶段接入仿真数据解除卡死 2026-07-28 17:45:03 +08:00
zhengxuan.zhang 3e5d32e462 fix: 卡点日志三元表达式编译错误 2026-07-28 17:40:12 +08:00
zhengxuan.zhang 576ea98d7a feat: 检测任务向导卡点日志增强 2026-07-28 17:39:11 +08:00
zhengxuan.zhang 5e2aa270a0 fix: 检测任务向导 Stage 1 卡在"当前流水线"无法进入下一步 2026-07-28 17:34:48 +08:00
zhengxuan.zhang 3da00f8508 fix: DebugPanelStateMetadata 引用更新为 DebugPanelLocalization 2026-07-28 17:14:03 +08:00
zhengxuan.zhang 35828fd03a docs: CncEditorViewModel 32 个命令属性添加 XML 中文注释 2026-07-28 17:09:37 +08:00