web: fix A=B/SWAP VFO ops, wire attenuator, TUN button, FNP filter overlay

- Add freq_a command: sets VFO A regardless of active VFO; fixes A=B and
  SWAP when VFO B is active (prev. sent freq_b which overwrote wrong VFO)
- Add pend("freq") to B=A / A=B / SWAP to guard local display during round-trip
- RX step attenuator: HPSDRNetwork.SetStepAtten → bytes 1442/1443 in HP packet;
  WebServer attn command; MainForm FAtten + SyncWebAttn; attSel.onchange in JS
- TUN mode: set_tun WebSocket command wired to ApplyTUN(); toneBtn toggles
  with on/off highlight and pending protection; tuning field in state JSON
- FNP button opens semi-transparent filter overlay (10 buttons, 5×2 grid)
  with mode-appropriate widths (SSB/CW/AM/FM); active filter highlighted;
  cur.filter_bw updated immediately on click so passband redraws within 50ms

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-09 15:04:23 +03:00
co-authored by Claude Sonnet 4.6
parent 9f208006aa
commit 154b6eccba
4 changed files with 165 additions and 20 deletions
+41 -4
View File
@@ -126,6 +126,9 @@ type
TWebCmdCenter = procedure(Hz: Double) of object;
TWebCmdMOX = procedure(On_: Boolean) of object;
TWebCmdDrive = procedure(V: Integer) of object;
TWebCmdFreqA = procedure(Hz: Double) of object;
TWebCmdAttn = procedure(Idx: Integer) of object;
TWebCmdTun = procedure(On_: Boolean) of object;
// ── Главный класс сервера ─────────────────────────────────────────────────
TWebServer = class
@@ -210,6 +213,11 @@ type
FOnDrive: TWebCmdDrive;
FTransmitting: Boolean;
FDriveLevel: Integer;
FOnFreqA: TWebCmdFreqA;
FOnAttn: TWebCmdAttn;
FAttnIdx: Integer;
FOnTun: TWebCmdTun;
FTuning: Boolean;
FWebClientActive: Boolean;
@@ -253,7 +261,8 @@ type
NRMode, NBMode: Integer; SNB, ANF: Boolean;
CenterHz: Double; FilterIdx: Integer;
VfoB: Double; ActiveVfo: Integer;
Transmitting: Boolean; DriveLevel: Integer);
Transmitting: Boolean; DriveLevel: Integer;
AttnIdx: Integer; Tuning: Boolean);
property WebClientActive: Boolean read FWebClientActive;
@@ -279,6 +288,9 @@ type
property OnCenter: TWebCmdCenter read FOnCenter write FOnCenter;
property OnMOX: TWebCmdMOX read FOnMOX write FOnMOX;
property OnDrive: TWebCmdDrive read FOnDrive write FOnDrive;
property OnFreqA: TWebCmdFreqA read FOnFreqA write FOnFreqA;
property OnAttn: TWebCmdAttn read FOnAttn write FOnAttn;
property OnTun: TWebCmdTun read FOnTun write FOnTun;
end;
implementation
@@ -1004,6 +1016,26 @@ begin
if V > 100 then V := 100;
FStateLock.Enter; FDriveLevel := V; FStateLock.Leave;
if Assigned(FOnDrive) then FOnDrive(V);
end
else if Cmd = 'set_tun' then
begin
On_ := JsonGetBool(Json, 'on', FTuning);
FStateLock.Enter; FTuning := On_; FStateLock.Leave;
if Assigned(FOnTun) then FOnTun(On_);
end
else if Cmd = 'freq_a' then
begin
HzF := JsonGetFloat(Json, 'hz', FFreq);
FStateLock.Enter; FFreq := HzF; FStateLock.Leave;
if Assigned(FOnFreqA) then FOnFreqA(HzF);
end
else if Cmd = 'attn' then
begin
Idx := JsonGetInt(Json, 'idx', FAttnIdx);
if Idx < 0 then Idx := 0;
if Idx > 2 then Idx := 2;
FStateLock.Enter; FAttnIdx := Idx; FStateLock.Leave;
if Assigned(FOnAttn) then FOnAttn(Idx);
end;
end;
@@ -1101,7 +1133,7 @@ begin
'"wf_agc":%s,"wf_nf":%s,"band_idx":%d,"smeter_dbm":%.1f,' +
'"running":%s,"mute":%s,"ctun":%s,' +
'"nr_mode":%d,"nr":%s,"nb_mode":%d,"nb":%s,"snb":%s,"anf":%s,"connected":%s,' +
'"transmitting":%s,"drive":%d}',
'"transmitting":%s,"drive":%d,"attn_idx":%d,"tuning":%s}',
[FFreq, FVfoB, FActiveVfo,
FMode, MODE_N[FMode mod 8],
FFilterIdx, FFilterBW,
@@ -1121,7 +1153,9 @@ begin
BoolToStr(FANF, 'true', 'false'),
BoolToStr(FConnected, 'true', 'false'),
BoolToStr(FTransmitting, 'true', 'false'),
FDriveLevel
FDriveLevel,
FAttnIdx,
BoolToStr(FTuning, 'true', 'false')
]);
finally
FStateLock.Leave;
@@ -1187,7 +1221,8 @@ procedure TWebServer.PushSpectrum(
NRMode, NBMode: Integer; SNB, ANF: Boolean;
CenterHz: Double; FilterIdx: Integer;
VfoB: Double; ActiveVfo: Integer;
Transmitting: Boolean; DriveLevel: Integer);
Transmitting: Boolean; DriveLevel: Integer;
AttnIdx: Integer; Tuning: Boolean);
var N, i: Integer;
begin
if not FRunning then Exit;
@@ -1221,6 +1256,8 @@ begin
FActiveVfo := ActiveVfo;
FTransmitting := Transmitting;
FDriveLevel := DriveLevel;
FAttnIdx := AttnIdx;
FTuning := Tuning;
finally
FStateLock.Leave;
end;