Phase 3 (batch 5): route FM step through controller command

FM step is the only FM control exposed to another frontend (web:
SyncWebFMStep in, FWebServer.FMStepIdx out), so it's the FM param with
real cross-frontend value.

- TRadioController.SetFMStep clamps and fires OnStateChanged(rfFMStepIdx).
- OnControllerState updates the step dropdown, pushes FMStepIdx to the web
  server, and sets the FSpecView FM grid step (when in FM mode).
- MainForm.SetFMStep is now a thin wrapper over the command, so existing
  callers (band restore, dropdown select, web sync, XVTR restore) are
  unchanged.

FM squelch/CTCSS/repeater are intentionally left as-is: they are UI-only
(no web/CAT/daemon exposure) and already operate on controller state
fields, so routing them through commands adds ceremony without value for
the swappable-UI/daemon goals; CTCSS would also need CTCSS_TONES relocated
to a shared unit and repeater needs the network helpers (XvtrTranslate/
ActiveTXFreqHz) that belong to the heavy-command batch.

Builds clean (cocoa).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Uladzimir Karpenka
2026-06-04 15:10:44 +03:00
co-authored by Claude Opus 4.8
parent ad21516d48
commit 7d3570346f
2 changed files with 16 additions and 6 deletions
+11 -5
View File
@@ -1453,6 +1453,13 @@ begin
FSpecView.WfAGCEnabled := FController.FWfAGCEnabled; FSpecView.WfAGCEnabled := FController.FWfAGCEnabled;
rfWfNF: rfWfNF:
FSpecView.WfNFEnabled := FController.FWfNFEnabled; FSpecView.WfNFEnabled := FController.FWfNFEnabled;
rfFMStepIdx:
begin
if FStepDropDown <> nil then FStepDropDown.SetItemIndex(FController.FFMStepIdx);
if FWebServer <> nil then FWebServer.FMStepIdx := FController.FFMStepIdx;
if (FController.FMode = MODE_FM) and (FSpecView <> nil) then
FSpecView.FMGridStepHz := FM_STEP_HZ[FController.FFMStepIdx];
end;
end; end;
finally finally
FSyncingFromController := False; FSyncingFromController := False;
@@ -5400,11 +5407,10 @@ end;
procedure TMainForm.SetFMStep(Idx: Integer); procedure TMainForm.SetFMStep(Idx: Integer);
begin begin
FController.FFMStepIdx := Idx; // Тонкая обёртка: команда контроллера обновит UI/web/спецвью через
if FStepDropDown <> nil then FStepDropDown.SetItemIndex(Idx); // OnControllerState(rfFMStepIdx). Сохранена для существующих вызовов
if FWebServer <> nil then FWebServer.FMStepIdx := Idx; // (RestoreBand, dropdown-select, web-sync, XVTR-restore).
if (FController.FMode = MODE_FM) and (FSpecView <> nil) then FController.SetFMStep(Idx);
FSpecView.FMGridStepHz := FM_STEP_HZ[Idx];
end; end;
procedure TMainForm.BtnFMStepClick(Sender: TObject); procedure TMainForm.BtnFMStepClick(Sender: TObject);
+5 -1
View File
@@ -516,7 +516,11 @@ procedure TRadioController.SetTune(On_: Boolean);
begin FTuning := On_; Changed(rfTuning); { TODO wiring: ApplyTUN } end; begin FTuning := On_; Changed(rfTuning); { TODO wiring: ApplyTUN } end;
procedure TRadioController.SetFMStep(Idx: Integer); procedure TRadioController.SetFMStep(Idx: Integer);
begin FFMStepIdx := Idx; Changed(rfFMStepIdx); { TODO wiring } end; begin
if Idx < 0 then Idx := 0 else if Idx > 3 then Idx := 3; // FM_STEP_COUNT = 4
FFMStepIdx := Idx;
Changed(rfFMStepIdx);
end;
procedure TRadioController.SetFMCTCSS(On_: Boolean); procedure TRadioController.SetFMCTCSS(On_: Boolean);
begin FFMCTCSSOn := On_; Changed(rfFMCTCSS); { TODO wiring } end; begin FFMCTCSSOn := On_; Changed(rfFMCTCSS); { TODO wiring } end;