多语支持
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
using ChromeboxFanControl.Properties;
|
||||
using ScottPlot;
|
||||
using ScottPlot.WinForms;
|
||||
|
||||
@@ -18,6 +19,7 @@ public sealed class MainForm : Form
|
||||
private readonly TextBox _txtFanDutyArgs = new();
|
||||
private readonly TextBox _txtAutoFanArgs = new();
|
||||
private readonly ComboBox _cmbTempSource = new();
|
||||
private readonly ComboBox _cmbLanguage = new();
|
||||
private readonly NumericUpDown _nudFailCount = new();
|
||||
private readonly NumericUpDown _nudFailPct = new();
|
||||
private readonly CheckBox _chkFailAuto = new();
|
||||
@@ -25,7 +27,7 @@ public sealed class MainForm : Form
|
||||
private readonly NumericUpDown _nudChartPoints = new();
|
||||
private readonly NotifyIcon _tray = new();
|
||||
private readonly ContextMenuStrip _trayMenu = new();
|
||||
private readonly ToolStripMenuItem _miPause = new("暂停控制");
|
||||
private readonly ToolStripMenuItem _miPause;
|
||||
private readonly object _seriesLock = new();
|
||||
private readonly List<double> _tSec = new();
|
||||
private readonly List<double> _temps = new();
|
||||
@@ -37,7 +39,8 @@ public sealed class MainForm : Form
|
||||
|
||||
public MainForm()
|
||||
{
|
||||
Text = "Chromebox 风扇温控";
|
||||
_miPause = new ToolStripMenuItem(Resources.TrayPause);
|
||||
Text = Resources.AppTitle;
|
||||
Size = new Size(960, 700);
|
||||
StartPosition = FormStartPosition.CenterScreen;
|
||||
MinimumSize = new Size(800, 500);
|
||||
@@ -62,9 +65,9 @@ public sealed class MainForm : Form
|
||||
{
|
||||
var tabs = new TabControl { Dock = DockStyle.Fill };
|
||||
|
||||
var tabMonitor = new TabPage("监控");
|
||||
var tabCurve = new TabPage("曲线");
|
||||
var tabAdv = new TabPage("高级");
|
||||
var tabMonitor = new TabPage(Resources.TabMonitor);
|
||||
var tabCurve = new TabPage(Resources.TabCurve);
|
||||
var tabAdv = new TabPage(Resources.TabAdvanced);
|
||||
|
||||
tabs.TabPages.Add(tabMonitor);
|
||||
tabs.TabPages.Add(tabCurve);
|
||||
@@ -75,7 +78,7 @@ public sealed class MainForm : Form
|
||||
_lblStatus.Dock = DockStyle.Bottom;
|
||||
_lblStatus.Padding = new Padding(8, 4, 8, 4);
|
||||
_lblStatus.AutoEllipsis = true;
|
||||
_lblStatus.Text = "启动中…";
|
||||
_lblStatus.Text = Resources.StatusStarting;
|
||||
|
||||
var panelChart = new Panel { Dock = DockStyle.Fill };
|
||||
panelChart.Controls.Add(_chart);
|
||||
@@ -91,14 +94,14 @@ public sealed class MainForm : Form
|
||||
_gridCurve.Columns.Add(new DataGridViewTextBoxColumn
|
||||
{
|
||||
Name = "colTemp",
|
||||
HeaderText = "温度 (°C)",
|
||||
HeaderText = Resources.GridColTemp,
|
||||
ReadOnly = true,
|
||||
Width = 80
|
||||
});
|
||||
_gridCurve.Columns.Add(new DataGridViewTextBoxColumn
|
||||
{
|
||||
Name = "colDuty",
|
||||
HeaderText = "占空比 0–100",
|
||||
HeaderText = Resources.GridColDuty,
|
||||
Width = 100
|
||||
});
|
||||
for (var i = 0; i < 14; i++)
|
||||
@@ -112,9 +115,9 @@ public sealed class MainForm : Form
|
||||
FlowDirection = FlowDirection.LeftToRight,
|
||||
Padding = new Padding(8)
|
||||
};
|
||||
var btnSave = new Button { Text = "保存并应用", AutoSize = true };
|
||||
var btnSave = new Button { Text = Resources.BtnSaveApply, AutoSize = true };
|
||||
btnSave.Click += (_, _) => SaveFromUi();
|
||||
var btnDefault = new Button { Text = "恢复默认曲线", AutoSize = true };
|
||||
var btnDefault = new Button { Text = Resources.BtnRestoreDefault, AutoSize = true };
|
||||
btnDefault.Click += (_, _) =>
|
||||
{
|
||||
var def = new AppConfig();
|
||||
@@ -138,41 +141,45 @@ public sealed class MainForm : Form
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
ColumnCount = 2,
|
||||
RowCount = 12,
|
||||
RowCount = 13,
|
||||
Padding = new Padding(12)
|
||||
};
|
||||
flp.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 35));
|
||||
flp.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 65));
|
||||
|
||||
var row = 0;
|
||||
AddRow(flp, row++, "ectool 路径", _txtEctool);
|
||||
AddRow(flp, row++, "轮询间隔 (ms)", _nudPoll);
|
||||
AddRow(flp, row++, Resources.LblLanguage, _cmbLanguage);
|
||||
_cmbLanguage.DropDownStyle = ComboBoxStyle.DropDownList;
|
||||
_cmbLanguage.Items.AddRange([Resources.LangAuto, Resources.LangEn, Resources.LangZhHans, Resources.LangZhHant]);
|
||||
|
||||
AddRow(flp, row++, Resources.LblEctoolPath, _txtEctool);
|
||||
AddRow(flp, row++, Resources.LblPollInterval, _nudPoll);
|
||||
_nudPoll.Minimum = 250;
|
||||
_nudPoll.Maximum = 60_000;
|
||||
_nudPoll.Increment = 250;
|
||||
|
||||
AddRow(flp, row++, "每 N 轮读 RPM", _nudRpmEvery);
|
||||
AddRow(flp, row++, Resources.LblRpmEvery, _nudRpmEvery);
|
||||
_nudRpmEvery.Minimum = 1;
|
||||
_nudRpmEvery.Maximum = 100;
|
||||
|
||||
AddRow(flp, row++, "读转速参数 (空格分隔)", _txtFanRpmArgs);
|
||||
AddRow(flp, row++, "读占空比参数 (空=跳过)", _txtFanDutyArgs);
|
||||
AddRow(flp, row++, Resources.LblFanRpmArgs, _txtFanRpmArgs);
|
||||
AddRow(flp, row++, Resources.LblFanDutyArgs, _txtFanDutyArgs);
|
||||
|
||||
AddRow(flp, row++, "恢复自动风扇参数", _txtAutoFanArgs);
|
||||
AddRow(flp, row++, Resources.LblAutoFanArgs, _txtAutoFanArgs);
|
||||
|
||||
AddRow(flp, row++, "温度来源", _cmbTempSource);
|
||||
AddRow(flp, row++, Resources.LblTempSource, _cmbTempSource);
|
||||
_cmbTempSource.DropDownStyle = ComboBoxStyle.DropDownList;
|
||||
_cmbTempSource.Items.AddRange(["AverageCore", "MaxCore"]);
|
||||
|
||||
AddRow(flp, row++, "连续失败进入安全模式 (次)", _nudFailCount);
|
||||
AddRow(flp, row++, Resources.LblFailCount, _nudFailCount);
|
||||
_nudFailCount.Minimum = 1;
|
||||
_nudFailCount.Maximum = 100;
|
||||
|
||||
AddRow(flp, row++, "安全模式固定占空比 (%)", _nudFailPct);
|
||||
AddRow(flp, row++, Resources.LblFailPct, _nudFailPct);
|
||||
_nudFailPct.Minimum = 0;
|
||||
_nudFailPct.Maximum = 100;
|
||||
|
||||
_chkFailAuto.Text = "安全模式使用 autofanctrl(不用固定占空比)";
|
||||
_chkFailAuto.Text = Resources.ChkFailAuto;
|
||||
_chkFailAuto.AutoSize = true;
|
||||
var failPanel = new FlowLayoutPanel
|
||||
{
|
||||
@@ -182,19 +189,19 @@ public sealed class MainForm : Form
|
||||
WrapContents = false
|
||||
};
|
||||
failPanel.Controls.Add(_chkFailAuto);
|
||||
flp.Controls.Add(new System.Windows.Forms.Label { Text = "安全模式策略", AutoSize = true, Anchor = AnchorStyles.Left }, 0, row);
|
||||
flp.Controls.Add(new System.Windows.Forms.Label { Text = Resources.LblFailStrategy, AutoSize = true, Anchor = AnchorStyles.Left }, 0, row);
|
||||
flp.Controls.Add(failPanel, 1, row++);
|
||||
|
||||
AddRow(flp, row++, "图表保留时长 (分钟)", _nudChartMin);
|
||||
AddRow(flp, row++, Resources.LblChartMin, _nudChartMin);
|
||||
_nudChartMin.Minimum = 1;
|
||||
_nudChartMin.Maximum = 120;
|
||||
|
||||
AddRow(flp, row++, "图表最大点数", _nudChartPoints);
|
||||
AddRow(flp, row++, Resources.LblChartPoints, _nudChartPoints);
|
||||
_nudChartPoints.Minimum = 100;
|
||||
_nudChartPoints.Maximum = 10_000;
|
||||
_nudChartPoints.Increment = 100;
|
||||
|
||||
var btnSaveAdv = new Button { Text = "保存高级设置", AutoSize = true, Dock = DockStyle.Bottom };
|
||||
var btnSaveAdv = new Button { Text = Resources.BtnSaveAdvanced, AutoSize = true, Dock = DockStyle.Bottom };
|
||||
btnSaveAdv.Click += (_, _) => SaveFromUi();
|
||||
tabAdv.Controls.Add(btnSaveAdv);
|
||||
tabAdv.Controls.Add(flp);
|
||||
@@ -211,7 +218,7 @@ public sealed class MainForm : Form
|
||||
|
||||
private void WireTray()
|
||||
{
|
||||
_tray.Text = "Chromebox 风扇温控";
|
||||
_tray.Text = Resources.AppTitle;
|
||||
_tray.Visible = true;
|
||||
_tray.Icon = SystemIcons.Application;
|
||||
_tray.DoubleClick += (_, _) => ShowFromTray();
|
||||
@@ -219,13 +226,11 @@ public sealed class MainForm : Form
|
||||
{
|
||||
TogglePause();
|
||||
};
|
||||
_trayMenu.Items.Add("打开主窗口", null, (_, _) => ShowFromTray());
|
||||
_trayMenu.Items.Add(Resources.TrayOpen, null, (_, _) => ShowFromTray());
|
||||
_trayMenu.Items.Add(_miPause);
|
||||
_trayMenu.Items.Add("关于", null, (_, _) =>
|
||||
MessageBox.Show(this,
|
||||
"Chromebox 风扇温控\n\n使用 LibreHardwareMonitor 读取 CPU 温度,通过 crosec ectool 控制风扇。\n\n请以管理员身份运行。",
|
||||
Text, MessageBoxButtons.OK, MessageBoxIcon.Information));
|
||||
_trayMenu.Items.Add("退出", null, (_, _) => Close());
|
||||
_trayMenu.Items.Add(Resources.TrayAbout, null, (_, _) =>
|
||||
MessageBox.Show(this, Resources.AboutMessage, Text, MessageBoxButtons.OK, MessageBoxIcon.Information));
|
||||
_trayMenu.Items.Add(Resources.TrayExit, null, (_, _) => Close());
|
||||
_tray.ContextMenuStrip = _trayMenu;
|
||||
}
|
||||
|
||||
@@ -242,11 +247,16 @@ public sealed class MainForm : Form
|
||||
if (_fan == null)
|
||||
return;
|
||||
_fan.Paused = !_fan.Paused;
|
||||
_miPause.Text = _fan.Paused ? "恢复控制" : "暂停控制";
|
||||
_miPause.Text = _fan.Paused ? Resources.TrayResume : Resources.TrayPause;
|
||||
}
|
||||
|
||||
private static readonly string[] LanguageValues = ["auto", "en", "zh-Hans", "zh-Hant"];
|
||||
|
||||
private void ApplyConfigToUi()
|
||||
{
|
||||
var langIdx = Array.IndexOf(LanguageValues, _config.Language);
|
||||
_cmbLanguage.SelectedIndex = langIdx >= 0 ? langIdx : 0;
|
||||
|
||||
_txtEctool.Text = _config.EctoolPath;
|
||||
_nudPoll.Value = _config.PollIntervalMs;
|
||||
_nudRpmEvery.Value = _config.FanRpmPollEveryNCycles;
|
||||
@@ -268,8 +278,12 @@ public sealed class MainForm : Form
|
||||
|
||||
private AppConfig CloneConfigFromUi()
|
||||
{
|
||||
var langIdx = _cmbLanguage.SelectedIndex;
|
||||
var lang = langIdx >= 0 && langIdx < LanguageValues.Length ? LanguageValues[langIdx] : "auto";
|
||||
|
||||
var c = new AppConfig
|
||||
{
|
||||
Language = lang,
|
||||
EctoolPath = _txtEctool.Text.Trim(),
|
||||
PollIntervalMs = (int)_nudPoll.Value,
|
||||
FanRpmPollEveryNCycles = (int)_nudRpmEvery.Value,
|
||||
@@ -313,8 +327,8 @@ public sealed class MainForm : Form
|
||||
|
||||
var plt = _curveChart.Plot;
|
||||
plt.Clear();
|
||||
plt.Axes.Left.Label.Text = "占空比 (%)";
|
||||
plt.Axes.Bottom.Label.Text = "温度 (°C)";
|
||||
plt.Axes.Left.Label.Text = Resources.CurveChartDuty;
|
||||
plt.Axes.Bottom.Label.Text = Resources.CurveChartTemp;
|
||||
plt.Axes.SetLimitsX(0, 100);
|
||||
plt.Axes.SetLimitsY(0, 100);
|
||||
|
||||
@@ -326,6 +340,7 @@ public sealed class MainForm : Form
|
||||
scatter.MarkerSize = 6;
|
||||
}
|
||||
|
||||
plt.Font.Automatic();
|
||||
_curveChart.Refresh();
|
||||
}
|
||||
|
||||
@@ -336,21 +351,25 @@ public sealed class MainForm : Form
|
||||
var rpmArgs = SplitArgs(_txtFanRpmArgs.Text);
|
||||
if (rpmArgs.Length == 0)
|
||||
{
|
||||
MessageBox.Show(this, "读转速参数不能为空。", Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
MessageBox.Show(this, Resources.ErrRpmArgsEmpty, Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
var autoArgs = SplitArgs(_txtAutoFanArgs.Text);
|
||||
if (autoArgs.Length == 0)
|
||||
{
|
||||
MessageBox.Show(this, "恢复自动风扇参数不能为空。", Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
MessageBox.Show(this, Resources.ErrAutoFanArgsEmpty, Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
var langBefore = _config.Language;
|
||||
_config = CloneConfigFromUi();
|
||||
_config.SaveUser();
|
||||
_fan?.UpdateConfig(_config);
|
||||
MessageBox.Show(this, "已保存。", Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
var msg = Resources.MsgSaved;
|
||||
if (langBefore != _config.Language)
|
||||
msg = Resources.MsgRestartToApplyLanguage;
|
||||
MessageBox.Show(this, msg, Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -388,11 +407,11 @@ public sealed class MainForm : Form
|
||||
var dVal = e.ActualDutyPercent ?? e.TargetDutyPercent;
|
||||
var dStr = dVal.HasValue ? $"{dVal} %" : "—";
|
||||
var rStr = e.Rpm.HasValue ? $"{e.Rpm} RPM" : "—";
|
||||
var state = e.Paused ? "已暂停" : e.FailSafe ? "安全模式" : "运行中";
|
||||
var state = e.Paused ? Resources.StatusPaused : e.FailSafe ? Resources.StatusFailSafe : Resources.StatusRunning;
|
||||
_lblStatus.Text =
|
||||
$"{state} 温度: {tStr} 目标占空比: {dStr} 转速: {rStr} ectool: {e.LastEctoolMessage ?? "—"}";
|
||||
$"{state} {Resources.LabelTemp} {tStr} {Resources.LabelTargetDuty} {dStr} {Resources.LabelRpm} {rStr} ectool: {e.LastEctoolMessage ?? "—"}";
|
||||
|
||||
_tray.Text = $"Chromebox {tStr} {dStr}";
|
||||
_tray.Text = $"{Resources.AppTitle} {tStr} {dStr}";
|
||||
|
||||
RebuildChart();
|
||||
}
|
||||
@@ -435,14 +454,14 @@ public sealed class MainForm : Form
|
||||
var plt = _chart.Plot;
|
||||
plt.Clear();
|
||||
|
||||
plt.Axes.Left.Label.Text = "Temperature (°C)";
|
||||
plt.Axes.Bottom.Label.Text = "Time (s)";
|
||||
plt.Axes.Left.Label.Text = Resources.ChartTemp;
|
||||
plt.Axes.Bottom.Label.Text = Resources.ChartTime;
|
||||
plt.Axes.Right.IsVisible = true;
|
||||
plt.Axes.Right.Label.Text = "Duty (%)";
|
||||
plt.Axes.Right.Label.Text = Resources.ChartDuty;
|
||||
|
||||
if (_yRpmAxis == null)
|
||||
_yRpmAxis = plt.Axes.AddRightAxis();
|
||||
_yRpmAxis.Label.Text = "RPM";
|
||||
_yRpmAxis.Label.Text = Resources.ChartRpm;
|
||||
|
||||
if (x.Length > 0)
|
||||
{
|
||||
@@ -509,12 +528,13 @@ public sealed class MainForm : Form
|
||||
|
||||
LegendItem[] leg =
|
||||
[
|
||||
new() { LineColor = Colors.Blue, LineWidth = 2, LabelText = "°C" },
|
||||
new() { LineColor = Colors.Orange, LineWidth = 2, LabelText = "Duty %" },
|
||||
new() { LineColor = Colors.Green, LineWidth = 2, LabelText = "RPM" }
|
||||
new() { LineColor = Colors.Blue, LineWidth = 2, LabelText = Resources.LegendCelsius },
|
||||
new() { LineColor = Colors.Orange, LineWidth = 2, LabelText = Resources.LegendDuty },
|
||||
new() { LineColor = Colors.Green, LineWidth = 2, LabelText = Resources.ChartRpm }
|
||||
];
|
||||
plt.ShowLegend(leg, Alignment.UpperRight);
|
||||
plt.Legend.Orientation = ScottPlot.Orientation.Horizontal;
|
||||
plt.Font.Automatic();
|
||||
_chart.Refresh();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user