Add per-channel independent limit controls
- Separate Lim A / Lim B trackbars (0-200, default 30 each) - Separate Scale A / Scale B checkboxes (clamp vs scale per channel) - State.SetLimitA/SetLimitB with independent LimitModeA/LimitModeB - ConsumeTick applies per-channel limit and mode
This commit is contained in:
+74
-41
@@ -24,17 +24,20 @@ public class MainForm : Form
|
||||
|
||||
bool _closingFromTray;
|
||||
|
||||
readonly ProgressBar _gaugeSendA;
|
||||
readonly ProgressBar _gaugeSendB;
|
||||
readonly HeatMap _heatA;
|
||||
readonly HeatMap _heatB;
|
||||
readonly ProgressBar _gaugeRecvA;
|
||||
readonly ProgressBar _gaugeRecvB;
|
||||
readonly Label _lblSendA;
|
||||
readonly Label _lblSendB;
|
||||
readonly Label _lblRecvA;
|
||||
readonly Label _lblRecvB;
|
||||
readonly TrackBar _limitBar;
|
||||
readonly Label _lblLimit;
|
||||
readonly CheckBox _chkScale;
|
||||
readonly TrackBar _limitBarA;
|
||||
readonly TrackBar _limitBarB;
|
||||
readonly Label _lblLimitA;
|
||||
readonly Label _lblLimitB;
|
||||
readonly CheckBox _chkScaleA;
|
||||
readonly CheckBox _chkScaleB;
|
||||
|
||||
readonly Icon _iconNeutral;
|
||||
readonly Icon _iconActive;
|
||||
@@ -55,7 +58,7 @@ public class MainForm : Form
|
||||
_loopCts = new CancellationTokenSource();
|
||||
|
||||
Text = $"Substation {typeof(MainForm).Assembly.GetName().Version}";
|
||||
ClientSize = new Size(420, 360);
|
||||
ClientSize = new Size(420, 410);
|
||||
FormBorderStyle = FormBorderStyle.FixedSingle;
|
||||
MaximizeBox = false;
|
||||
StartPosition = FormStartPosition.CenterScreen;
|
||||
@@ -137,39 +140,33 @@ public class MainForm : Form
|
||||
Size = new Size(48, 20),
|
||||
Font = new Font(Font.FontFamily, 9, FontStyle.Bold)
|
||||
};
|
||||
_gaugeSendA = new ProgressBar
|
||||
_heatA = new HeatMap(60)
|
||||
{
|
||||
Location = new Point(72, 160),
|
||||
Size = new Size(332, 20),
|
||||
Minimum = 0,
|
||||
Maximum = 100,
|
||||
Style = ProgressBarStyle.Continuous
|
||||
Location = new Point(72, 158),
|
||||
Size = new Size(332, 22)
|
||||
};
|
||||
_lblSendB = new Label
|
||||
{
|
||||
Text = "Send B",
|
||||
Location = new Point(16, 184),
|
||||
Location = new Point(16, 188),
|
||||
Size = new Size(48, 20),
|
||||
Font = new Font(Font.FontFamily, 9, FontStyle.Bold)
|
||||
};
|
||||
_gaugeSendB = new ProgressBar
|
||||
_heatB = new HeatMap(60)
|
||||
{
|
||||
Location = new Point(72, 184),
|
||||
Size = new Size(332, 20),
|
||||
Minimum = 0,
|
||||
Maximum = 100,
|
||||
Style = ProgressBarStyle.Continuous
|
||||
Location = new Point(72, 186),
|
||||
Size = new Size(332, 22)
|
||||
};
|
||||
_lblRecvA = new Label
|
||||
{
|
||||
Text = "Recv A",
|
||||
Location = new Point(16, 212),
|
||||
Location = new Point(16, 216),
|
||||
Size = new Size(48, 20),
|
||||
Font = new Font(Font.FontFamily, 9, FontStyle.Bold)
|
||||
};
|
||||
_gaugeRecvA = new ProgressBar
|
||||
{
|
||||
Location = new Point(72, 212),
|
||||
Location = new Point(72, 216),
|
||||
Size = new Size(332, 20),
|
||||
Minimum = 0,
|
||||
Maximum = 200,
|
||||
@@ -178,47 +175,73 @@ public class MainForm : Form
|
||||
_lblRecvB = new Label
|
||||
{
|
||||
Text = "Recv B",
|
||||
Location = new Point(16, 236),
|
||||
Location = new Point(16, 242),
|
||||
Size = new Size(48, 20),
|
||||
Font = new Font(Font.FontFamily, 9, FontStyle.Bold)
|
||||
};
|
||||
_gaugeRecvB = new ProgressBar
|
||||
{
|
||||
Location = new Point(72, 236),
|
||||
Location = new Point(72, 242),
|
||||
Size = new Size(332, 20),
|
||||
Minimum = 0,
|
||||
Maximum = 200,
|
||||
Style = ProgressBarStyle.Continuous
|
||||
};
|
||||
|
||||
_lblLimit = new Label
|
||||
_lblLimitA = new Label
|
||||
{
|
||||
Text = "Limit: 30",
|
||||
Location = new Point(16, 272),
|
||||
Size = new Size(64, 20),
|
||||
Text = "Lim A: 30",
|
||||
Location = new Point(16, 274),
|
||||
Size = new Size(56, 20),
|
||||
Font = new Font(Font.FontFamily, 9, FontStyle.Bold)
|
||||
};
|
||||
_limitBar = new TrackBar
|
||||
_limitBarA = new TrackBar
|
||||
{
|
||||
Location = new Point(80, 268),
|
||||
Size = new Size(240, 45),
|
||||
Location = new Point(72, 270),
|
||||
Size = new Size(250, 45),
|
||||
Minimum = 0,
|
||||
Maximum = 200,
|
||||
TickFrequency = 50,
|
||||
Value = 30
|
||||
};
|
||||
_limitBar.ValueChanged += OnLimitChanged;
|
||||
_chkScale = new CheckBox
|
||||
_limitBarA.ValueChanged += OnLimitChanged;
|
||||
_chkScaleA = new CheckBox
|
||||
{
|
||||
Text = "Scale",
|
||||
Location = new Point(328, 272),
|
||||
Location = new Point(328, 274),
|
||||
Size = new Size(76, 24),
|
||||
Checked = false
|
||||
};
|
||||
_chkScale.CheckedChanged += OnLimitChanged;
|
||||
_chkScaleA.CheckedChanged += OnLimitChanged;
|
||||
|
||||
_lblLimitB = new Label
|
||||
{
|
||||
Text = "Lim B: 30",
|
||||
Location = new Point(16, 312),
|
||||
Size = new Size(56, 20),
|
||||
Font = new Font(Font.FontFamily, 9, FontStyle.Bold)
|
||||
};
|
||||
_limitBarB = new TrackBar
|
||||
{
|
||||
Location = new Point(72, 308),
|
||||
Size = new Size(250, 45),
|
||||
Minimum = 0,
|
||||
Maximum = 200,
|
||||
TickFrequency = 50,
|
||||
Value = 30
|
||||
};
|
||||
_limitBarB.ValueChanged += OnLimitChanged;
|
||||
_chkScaleB = new CheckBox
|
||||
{
|
||||
Text = "Scale",
|
||||
Location = new Point(328, 312),
|
||||
Size = new Size(76, 24),
|
||||
Checked = false
|
||||
};
|
||||
_chkScaleB.CheckedChanged += OnLimitChanged;
|
||||
OnLimitChanged(null, EventArgs.Empty);
|
||||
|
||||
Controls.AddRange(new Control[] { _lblBle, _lblWs, _lblDeviceName, _txtDeviceName, _btnConnect, _btnTest, _btnMusic, _btnStop, _lblTrack, _lblSendA, _gaugeSendA, _lblSendB, _gaugeSendB, _lblRecvA, _gaugeRecvA, _lblRecvB, _gaugeRecvB, _lblLimit, _limitBar, _chkScale });
|
||||
Controls.AddRange(new Control[] { _lblBle, _lblWs, _lblDeviceName, _txtDeviceName, _btnConnect, _btnTest, _btnMusic, _btnStop, _lblTrack, _lblSendA, _heatA, _lblSendB, _heatB, _lblRecvA, _gaugeRecvA, _lblRecvB, _gaugeRecvB, _lblLimitA, _limitBarA, _chkScaleA, _lblLimitB, _limitBarB, _chkScaleB });
|
||||
|
||||
// Tray icon — three cached variants: neutral=gray, active=gold, hot=red-orange
|
||||
_iconNeutral = CreateVoltageIcon(Color.Gray);
|
||||
@@ -357,8 +380,14 @@ public class MainForm : Form
|
||||
_lblBle.Text = _device.IsConnected
|
||||
? $"BLE: connected ({_device.DeviceName})"
|
||||
: "BLE: disconnected";
|
||||
_gaugeSendA.Value = Math.Clamp(_state.LastIntensityA, 0, 100);
|
||||
_gaugeSendB.Value = Math.Clamp(_state.LastIntensityB, 0, 100);
|
||||
_heatA.AddTick(
|
||||
_state.LastFreqA ?? Array.Empty<byte>(),
|
||||
_state.LastIntA ?? Array.Empty<byte>(),
|
||||
_state.LastActiveA);
|
||||
_heatB.AddTick(
|
||||
_state.LastFreqB ?? Array.Empty<byte>(),
|
||||
_state.LastIntB ?? Array.Empty<byte>(),
|
||||
_state.LastActiveB);
|
||||
_gaugeRecvA.Value = Math.Clamp(_device.StrengthA, 0, 200);
|
||||
_gaugeRecvB.Value = Math.Clamp(_device.StrengthB, 0, 200);
|
||||
_btnTest.Enabled = !_server.HasClient && !IsTestRunning;
|
||||
@@ -443,10 +472,14 @@ public class MainForm : Form
|
||||
|
||||
void OnLimitChanged(object? sender, EventArgs e)
|
||||
{
|
||||
var max = _limitBar.Value;
|
||||
var mode = _chkScale.Checked ? LimitMode.Scale : LimitMode.Clamp;
|
||||
_state.SetLimit(max, mode);
|
||||
_lblLimit.Text = $"Limit: {max}";
|
||||
var maxA = _limitBarA.Value;
|
||||
var maxB = _limitBarB.Value;
|
||||
var modeA = _chkScaleA.Checked ? LimitMode.Scale : LimitMode.Clamp;
|
||||
var modeB = _chkScaleB.Checked ? LimitMode.Scale : LimitMode.Clamp;
|
||||
_state.SetLimitA(maxA, modeA);
|
||||
_state.SetLimitB(maxB, modeB);
|
||||
_lblLimitA.Text = $"Lim A: {maxA}";
|
||||
_lblLimitB.Text = $"Lim B: {maxB}";
|
||||
}
|
||||
|
||||
string _musicFilePath = "";
|
||||
|
||||
Reference in New Issue
Block a user