diff --git a/src/Core/Settings.cs b/src/Core/Settings.cs index a21252d..caf57c4 100644 --- a/src/Core/Settings.cs +++ b/src/Core/Settings.cs @@ -281,6 +281,11 @@ public string Key // null/"Auto" = 自动(默认), "" = 不显示, "{u}/s" = 自定义格式 public string UnitPanel { get; set; } = null; public string UnitTaskbar { get; set; } = null; + + // ★★★ [新增] 传感器ID强制覆盖 ★★★ + // 允许用户手动指定 "/gpu-nvidia/0/power/0" 等 ID + public string OverrideSensorId { get; set; } = ""; + public bool VisibleInPanel { get; set; } = true; public bool VisibleInTaskbar { get; set; } = false; diff --git a/src/System/HardwareServices/SensorMap.cs b/src/System/HardwareServices/SensorMap.cs index 4e1e891..06248a9 100644 --- a/src/System/HardwareServices/SensorMap.cs +++ b/src/System/HardwareServices/SensorMap.cs @@ -264,6 +264,40 @@ void RegisterTo(IHardware hw) // ★★★ 修改:委托给 FanMapper 专用类处理 ★★★ _fanMapper.ScanAndMapFans(computer, cfg, newMap); + // ============================================ + // ★★★ [新增] 用户强制覆盖逻辑 ★★★ + // ============================================ + if (cfg.MonitorItems != null) + { + foreach (var item in cfg.MonitorItems) + { + if (!string.IsNullOrEmpty(item.OverrideSensorId)) + { + string targetId = item.OverrideSensorId.Trim(); + ISensor? match = null; + + // 简单的线性全扫描 (毕竟是在 Rebuild 低频操作中,耗时可忽略) + computer.Accept(new HardwareVisitor(h => + { + foreach (var s in h.Sensors) + { + if (string.Equals(s.Identifier.ToString(), targetId, StringComparison.OrdinalIgnoreCase)) + { + match = s; + break; + } + } + })); + + if (match != null) + { + newMap[item.Key] = match; + System.Diagnostics.Debug.WriteLine($"[SensorMap] Override applied: {item.Key} -> {match.Name} ({match.Identifier})"); + } + } + } + } + // 2. 原子交换数据 (加锁) lock (_lock) { @@ -279,6 +313,23 @@ void RegisterTo(IHardware hw) } } + // ============================================ + // ★★★ [新增] 用于遍历寻找 Sensor 的访问器 ★★★ + // ============================================ + private class HardwareVisitor : IVisitor + { + private readonly Action _action; + public HardwareVisitor(Action action) { _action = action; } + public void VisitComputer(IComputer computer) => computer.Traverse(this); + public void VisitHardware(IHardware hardware) + { + _action(hardware); + foreach (var sub in hardware.SubHardware) sub.Accept(this); + } + public void VisitSensor(ISensor sensor) { } + public void VisitParameter(IParameter parameter) { } + } + // 复用 HardwareRules 的字符串匹配,避免重复造轮子 public static bool Has(string source, string sub) => HardwareRules.Has(source, sub); } diff --git a/src/UI/Controls/MonitorControls.cs b/src/UI/Controls/MonitorControls.cs index 3a61044..c6f66d0 100644 --- a/src/UI/Controls/MonitorControls.cs +++ b/src/UI/Controls/MonitorControls.cs @@ -3,6 +3,7 @@ using System.Windows.Forms; using LiteMonitor.src.Core; using LiteMonitor.src.SystemServices.InfoService; // [New] +using System.Linq; namespace LiteMonitor.src.UI.Controls { @@ -149,6 +150,23 @@ public MonitorItemRow(MonitorItemConfig item, bool isTaskbarMode) _btnUp, _btnDown }); + // ★★★ [新增] 高级设置按钮 (用于绑定特定传感器ID) ★★★ + var btnSettings = new Label + { + Text = "⚙", + AutoSize = true, + Cursor = Cursors.Hand, + ForeColor = UIColors.TextSub, + Font = new Font("Segoe UI Emoji", 9F), // 使用 Emoji 字体确保显示 + Location = new Point(MonitorLayout.X_COL3 - UIUtils.S(25), UIUtils.S(12)) // 放在 Checkbox 左侧 + }; + btnSettings.Click += (s, e) => ShowSensorOverrideDialog(); + + // 只有当有 OverrideSensorId 时显示不同颜色提示 + if (!string.IsNullOrEmpty(item.OverrideSensorId)) btnSettings.ForeColor = UIColors.Primary; + + this.Controls.Add(btnSettings); + // ★★★ 立即应用模式可见性 ★★★ ApplyModeVisibility(); } @@ -333,6 +351,55 @@ public void SyncToConfig() Config.VisibleInPanel = _chkPanel.Checked; Config.VisibleInTaskbar = _chkTaskbar.Checked; } + + private void ShowSensorOverrideDialog() + { + using (var form = new Form()) + { + form.Text = LanguageManager.T("Menu.SensorOverride") ?? "Sensor Override"; + form.Width = UIUtils.S(400); + form.Height = UIUtils.S(220); + form.StartPosition = FormStartPosition.CenterParent; + form.FormBorderStyle = FormBorderStyle.FixedDialog; + form.MaximizeBox = false; + form.MinimizeBox = false; + form.Font = new Font("Microsoft YaHei UI", 9F); + + var lbl = new Label { + Text = "指定传感器 ID / Specific Sensor ID:\n(e.g. /gpu-nvidia/0/power/0)", + AutoSize = true, + Location = new Point(20, 20) + }; + + // 查找当前应用的值 (如果有 override 显示 override,否则显示 actual) + string currentVal = Config.OverrideSensorId; + + var txt = new TextBox { + Text = currentVal, + Width = 340, + Location = new Point(20, 60) + }; + + var btnSave = new Button { Text = "OK", DialogResult = DialogResult.OK, Location = new Point(200, 100), Height = 30 }; + var btnCancel = new Button { Text = "Cancel", DialogResult = DialogResult.Cancel, Location = new Point(285, 100), Height = 30 }; + + // 简单的"清除"按钮 + var btnClear = new Button { Text = "Clear", Location = new Point(20, 100), Height = 30 }; + btnClear.Click += (s, e) => txt.Text = ""; + + form.Controls.AddRange(new Control[] { lbl, txt, btnSave, btnCancel, btnClear }); + form.AcceptButton = btnSave; + form.CancelButton = btnCancel; + + if (form.ShowDialog() == DialogResult.OK) + { + Config.OverrideSensorId = txt.Text.Trim(); + // 更新按钮颜色 + var btn = this.Controls.OfType