diff --git a/HkVisionPro.App/App.config b/HkVisionPro.App/App.config index a604f5c..e73105a 100644 --- a/HkVisionPro.App/App.config +++ b/HkVisionPro.App/App.config @@ -6,7 +6,7 @@ - + diff --git a/HkVisionPro.App/MainForm.Designer.cs b/HkVisionPro.App/MainForm.Designer.cs index 88ffca6..de87602 100644 --- a/HkVisionPro.App/MainForm.Designer.cs +++ b/HkVisionPro.App/MainForm.Designer.cs @@ -60,6 +60,11 @@ this.vmParamsConfigControl1 = new VMControls.Winform.Release.VmParamsConfigControl(); this.groupBox5 = new System.Windows.Forms.GroupBox(); this.lblRunState = new System.Windows.Forms.Label(); + this.lblTotalResult = new System.Windows.Forms.Label(); + this.lblComponent1 = new System.Windows.Forms.Label(); + this.lblLayer = new System.Windows.Forms.Label(); + this.lblComponent2 = new System.Windows.Forms.Label(); + this.lblStableOkTime = new System.Windows.Forms.Label(); this.groupBox1.SuspendLayout(); this.groupBox2.SuspendLayout(); this.groupBox3.SuspendLayout(); @@ -377,6 +382,11 @@ // // groupBox5 // + this.groupBox5.Controls.Add(this.lblStableOkTime); + this.groupBox5.Controls.Add(this.lblComponent2); + this.groupBox5.Controls.Add(this.lblLayer); + this.groupBox5.Controls.Add(this.lblComponent1); + this.groupBox5.Controls.Add(this.lblTotalResult); this.groupBox5.Controls.Add(this.lblRunState); this.groupBox5.Location = new System.Drawing.Point(23, 58); this.groupBox5.Name = "groupBox5"; @@ -387,13 +397,69 @@ // // lblRunState // - this.lblRunState.AutoSize = true; this.lblRunState.Font = new System.Drawing.Font("微软雅黑", 21.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134))); - this.lblRunState.Location = new System.Drawing.Point(32, 85); + this.lblRunState.Location = new System.Drawing.Point(6, 297); this.lblRunState.Name = "lblRunState"; - this.lblRunState.Size = new System.Drawing.Size(133, 39); + this.lblRunState.Size = new System.Drawing.Size(423, 71); this.lblRunState.TabIndex = 0; this.lblRunState.Text = "运行状态"; + this.lblRunState.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // lblTotalResult + // + this.lblTotalResult.AutoSize = true; + this.lblTotalResult.Font = new System.Drawing.Font("微软雅黑", 36F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.lblTotalResult.ForeColor = System.Drawing.Color.LimeGreen; + this.lblTotalResult.Location = new System.Drawing.Point(22, 88); + this.lblTotalResult.Name = "lblTotalResult"; + this.lblTotalResult.Size = new System.Drawing.Size(392, 64); + this.lblTotalResult.TabIndex = 1; + this.lblTotalResult.Text = "总结果:OK/NG"; + // + // lblComponent1 + // + this.lblComponent1.AutoSize = true; + this.lblComponent1.Font = new System.Drawing.Font("微软雅黑", 24F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.lblComponent1.ForeColor = System.Drawing.Color.Red; + this.lblComponent1.Location = new System.Drawing.Point(74, 158); + this.lblComponent1.Name = "lblComponent1"; + this.lblComponent1.Size = new System.Drawing.Size(248, 42); + this.lblComponent1.TabIndex = 2; + this.lblComponent1.Text = "组件1:OK/NG"; + // + // lblLayer + // + this.lblLayer.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(128)))), ((int)(((byte)(128)))), ((int)(((byte)(255))))); + this.lblLayer.Font = new System.Drawing.Font("微软雅黑", 24F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.lblLayer.ForeColor = System.Drawing.SystemColors.Control; + this.lblLayer.Location = new System.Drawing.Point(6, 20); + this.lblLayer.Name = "lblLayer"; + this.lblLayer.Size = new System.Drawing.Size(423, 64); + this.lblLayer.TabIndex = 3; + this.lblLayer.Text = "当前层:A-Layer"; + this.lblLayer.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // lblComponent2 + // + this.lblComponent2.AutoSize = true; + this.lblComponent2.Font = new System.Drawing.Font("微软雅黑", 24F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.lblComponent2.ForeColor = System.Drawing.Color.Red; + this.lblComponent2.Location = new System.Drawing.Point(74, 204); + this.lblComponent2.Name = "lblComponent2"; + this.lblComponent2.Size = new System.Drawing.Size(248, 42); + this.lblComponent2.TabIndex = 4; + this.lblComponent2.Text = "组件2:OK/NG"; + // + // lblStableOkTime + // + this.lblStableOkTime.AutoSize = true; + this.lblStableOkTime.Font = new System.Drawing.Font("微软雅黑", 15.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.lblStableOkTime.ForeColor = System.Drawing.Color.Gray; + this.lblStableOkTime.Location = new System.Drawing.Point(76, 255); + this.lblStableOkTime.Name = "lblStableOkTime"; + this.lblStableOkTime.Size = new System.Drawing.Size(117, 28); + this.lblStableOkTime.TabIndex = 5; + this.lblStableOkTime.Text = "维持时间:"; // // MainForm // @@ -465,6 +531,11 @@ private System.Windows.Forms.GroupBox groupBox5; private System.Windows.Forms.Label lblRunState; private System.Windows.Forms.Button btnAutoRun; + private System.Windows.Forms.Label lblTotalResult; + private System.Windows.Forms.Label lblComponent1; + private System.Windows.Forms.Label lblLayer; + private System.Windows.Forms.Label lblComponent2; + private System.Windows.Forms.Label lblStableOkTime; } } diff --git a/HkVisionPro.App/MainForm.cs b/HkVisionPro.App/MainForm.cs index 3628676..8b6ff89 100644 --- a/HkVisionPro.App/MainForm.cs +++ b/HkVisionPro.App/MainForm.cs @@ -137,6 +137,11 @@ namespace HkVisionPro.App /// private readonly bool _autoRunEnabledAfterSolutionLoaded; + /// + /// 自动运行结果面板上次显示状态(用于层切换时重置结果显示)。 + /// + private AutoAssemblyState _lastDisplayedAutoAssemblyState = AutoAssemblyState.Idle; + /// /// ReaLTaiizor Poison 样式管理器(用于统一暗色主题风格元数据)。 /// @@ -224,8 +229,19 @@ namespace HkVisionPro.App private void InitializeAutoRunStatusPanel() { lblRunState.AutoSize = false; - lblRunState.Dock = DockStyle.Fill; lblRunState.TextAlign = ContentAlignment.MiddleCenter; + lblRunState.ForeColor = DarkThemeForeColor; + + lblLayer.TextAlign = ContentAlignment.MiddleCenter; + lblLayer.ForeColor = Color.White; + lblLayer.BackColor = GetLayerBackgroundColor(AutoAssemblyState.Idle); + + lblStableOkTime.ForeColor = Color.Gainsboro; + lblStableOkTime.Text = "维持时间:0/0 ms"; + + SetResultLabelStatus(lblTotalResult, "总结果", "待检测", Color.Gainsboro); + SetResultLabelStatus(lblComponent1, "组件1", "待检测", Color.Gainsboro); + SetResultLabelStatus(lblComponent2, "组件2", "待检测", Color.Gainsboro); var initMessage = _autoRunEnabledAfterSolutionLoaded ? "自动流程待启动(等待方案加载)" @@ -282,14 +298,42 @@ namespace HkVisionPro.App void UpdateAction() { + var elapsed = Math.Max(0, stableElapsedMilliseconds); + var target = Math.Max(0, stableTargetMilliseconds); + if (target > 0) + { + elapsed = Math.Min(elapsed, target); + } + lblRunState.ForeColor = GetAutoRunStateColor(state); lblRunState.Text = BuildAutoRunDisplayText( state, message, productIndex, activeProcedureName, - stableElapsedMilliseconds, - stableTargetMilliseconds); + elapsed, + target); + + lblLayer.BackColor = GetLayerBackgroundColor(state); + lblLayer.ForeColor = Color.White; + lblLayer.Text = BuildLayerDisplayText(state, activeProcedureName); + + lblStableOkTime.ForeColor = Color.Gainsboro; + lblStableOkTime.Text = $"维持时间:{elapsed}/{target} ms"; + + var stateChanged = state != _lastDisplayedAutoAssemblyState; + if (stateChanged && IsLayerInspectingState(state)) + { + SetResultLabelStatus(lblTotalResult, "总结果", "待检测", Color.Gainsboro); + SetResultLabelStatus(lblComponent1, "组件1", "待检测", Color.Gainsboro); + SetResultLabelStatus(lblComponent2, "组件2", "待检测", Color.Gainsboro); + } + else if (!IsLayerInspectingState(state)) + { + ApplyNonInspectingStateResultDisplay(state); + } + + _lastDisplayedAutoAssemblyState = state; } if (lblRunState.InvokeRequired) @@ -321,15 +365,9 @@ namespace HkVisionPro.App int stableTargetMilliseconds) { var displayProductIndex = productIndex <= 0 ? 1 : productIndex; - var displayProcedure = string.IsNullOrWhiteSpace(activeProcedureName) ? "-" : activeProcedureName; - var elapsed = Math.Max(0, stableElapsedMilliseconds); - var target = Math.Max(0, stableTargetMilliseconds); - if (target > 0) - { - elapsed = Math.Min(elapsed, target); - } - - return $"{GetAutoRunStateTitle(state)}\r\n产品序号:#{displayProductIndex}\r\n当前流程:{displayProcedure}\r\n稳定计时:{elapsed}/{target} ms\r\n状态描述:{message}"; + var displayProcedure = string.IsNullOrWhiteSpace(activeProcedureName) ? "-" : activeProcedureName.Trim(); + var displayMessage = string.IsNullOrWhiteSpace(message) ? "-" : message.Trim(); + return $"{GetAutoRunStateTitle(state)} | 产品#{displayProductIndex} | 流程:{displayProcedure} | {displayMessage}"; } /// @@ -384,6 +422,155 @@ namespace HkVisionPro.App } } + /// + /// 根据状态构造“当前层”标签展示文本。 + /// + /// 自动流程状态。 + /// 当前流程名。 + /// 层展示文本。 + private static string BuildLayerDisplayText(AutoAssemblyState state, string activeProcedureName) + { + var procedureName = string.IsNullOrWhiteSpace(activeProcedureName) ? "-" : activeProcedureName.Trim(); + switch (state) + { + case AutoAssemblyState.LayerAInspecting: + return $"当前层:A层({procedureName})"; + case AutoAssemblyState.LayerBInspecting: + return $"当前层:B层({procedureName})"; + case AutoAssemblyState.LayerCInspecting: + return $"当前层:C层({procedureName})"; + case AutoAssemblyState.ProductCompleted: + return "当前层:整机完成"; + case AutoAssemblyState.Faulted: + return "当前层:故障"; + case AutoAssemblyState.Stopped: + return "当前层:已停止"; + default: + return "当前层:空闲"; + } + } + + /// + /// 获取层标签背景色,保证白字可读性。 + /// + /// 自动流程状态。 + /// 背景色。 + private static Color GetLayerBackgroundColor(AutoAssemblyState state) + { + switch (state) + { + case AutoAssemblyState.LayerAInspecting: + return Color.FromArgb(38, 109, 190); + case AutoAssemblyState.LayerBInspecting: + return Color.FromArgb(179, 113, 36); + case AutoAssemblyState.LayerCInspecting: + return Color.FromArgb(108, 78, 163); + case AutoAssemblyState.ProductCompleted: + return Color.FromArgb(36, 128, 84); + case AutoAssemblyState.Faulted: + return Color.FromArgb(170, 55, 55); + case AutoAssemblyState.Stopped: + return Color.FromArgb(88, 88, 92); + default: + return Color.FromArgb(68, 68, 72); + } + } + + /// + /// 判断状态是否为层级检测状态。 + /// + /// 自动流程状态。 + /// 是否处于 A/B/C 层检测。 + private static bool IsLayerInspectingState(AutoAssemblyState state) + { + return state == AutoAssemblyState.LayerAInspecting + || state == AutoAssemblyState.LayerBInspecting + || state == AutoAssemblyState.LayerCInspecting; + } + + /// + /// 设置结果标签文本与颜色。 + /// + /// 目标标签。 + /// 标题。 + /// 值。 + /// 前景色。 + private static void SetResultLabelStatus(Label label, string title, string value, Color foreColor) + { + if (label == null) + { + return; + } + + label.ForeColor = foreColor; + label.Text = $"{title}:{value}"; + } + + /// + /// 根据流程状态更新非检测态的结果展示。 + /// + /// 自动流程状态。 + private void ApplyNonInspectingStateResultDisplay(AutoAssemblyState state) + { + if (state == AutoAssemblyState.ProductCompleted) + { + SetResultLabelStatus(lblTotalResult, "总结果", "OK", Color.LimeGreen); + SetResultLabelStatus(lblComponent1, "组件1", "OK", Color.LimeGreen); + SetResultLabelStatus(lblComponent2, "组件2", "OK", Color.LimeGreen); + return; + } + + if (state == AutoAssemblyState.Faulted) + { + SetResultLabelStatus(lblTotalResult, "总结果", "NG", Color.Red); + SetResultLabelStatus(lblComponent1, "组件1", "NG", Color.Red); + SetResultLabelStatus(lblComponent2, "组件2", "NG", Color.Red); + return; + } + + SetResultLabelStatus(lblTotalResult, "总结果", "待检测", Color.Gainsboro); + SetResultLabelStatus(lblComponent1, "组件1", "待检测", Color.Gainsboro); + SetResultLabelStatus(lblComponent2, "组件2", "待检测", Color.Gainsboro); + } + + /// + /// 根据当前流程输出判定结果刷新“总结果/组件结果”标签。 + /// + /// 组件1结果。 + /// 组件2结果。 + private void UpdateAutoRunResultByProcedureResult(string result1, string result2) + { + if (_autoAssemblyController == null || !_autoAssemblyController.IsRunning) + { + return; + } + + if (!IsHandleCreated || IsDisposed) + { + return; + } + + void UpdateAction() + { + var component1Ok = string.Equals(result1?.Trim(), "1", StringComparison.Ordinal); + var component2Ok = string.Equals(result2?.Trim(), "1", StringComparison.Ordinal); + var totalOk = component1Ok && component2Ok; + + SetResultLabelStatus(lblComponent1, "组件1", component1Ok ? "OK" : "NG", component1Ok ? Color.LimeGreen : Color.Red); + SetResultLabelStatus(lblComponent2, "组件2", component2Ok ? "OK" : "NG", component2Ok ? Color.LimeGreen : Color.Red); + SetResultLabelStatus(lblTotalResult, "总结果", totalOk ? "OK" : "NG", totalOk ? Color.LimeGreen : Color.Red); + } + + if (lblTotalResult.InvokeRequired) + { + lblTotalResult.BeginInvoke(new Action(UpdateAction)); + } + else + { + UpdateAction(); + } + } + /// /// 按配置构建自动装配流程参数。 /// @@ -1135,6 +1322,8 @@ namespace HkVisionPro.App var pairResult = isResult1Ok && isResult2Ok ? "OK" : "NG"; var overlayText = $"R1={result1}, R2={result2}, Total={pairResult}"; + UpdateAutoRunResultByProcedureResult(result1, result2); + var bitmap = GetProcedureOutputBitmap(procedure, _renderImageOutputName); if (bitmap == null) {