diff --git a/ChannelController.pas b/ChannelController.pas index 7defbd3..fb9efed 100644 --- a/ChannelController.pas +++ b/ChannelController.pas @@ -37,10 +37,12 @@ type FRadio: TRadioController; FActiveIdx: Integer; // -1 = нет активного канала FPreChannelPower: Integer; // drive % до применения канала (-1 = не сохранён) + FRestoringDrive: Boolean; // True пока юнит сам ставит drive (apply/restore) FOnActiveChanged: TChannelActiveEvent; FOnActivateXvtr: TChannelXvtrEvent; FOnDeactivateXvtr: TChannelNotifyEvent; procedure EmitActive(Active: Boolean; const Name: string); + procedure SetDriveGuarded(V: Integer); // SetDrive, не сбрасывающий память канала public constructor Create(ARadio: TRadioController); @@ -48,7 +50,7 @@ type procedure Apply(const Ch: TChannel); // применить канал к радио procedure CheckActive; // деактивировать при уходе с частоты procedure OnVfoTuned; // канальная оркестрация после SetVfoA - procedure ClearPreChannelPower; // ручное изменение drive снимает память + procedure OnDriveChanged; // реакция на rfDrive: внешнее изменение снимает память property ActiveIdx: Integer read FActiveIdx write FActiveIdx; property OnActiveChanged: TChannelActiveEvent read FOnActiveChanged write FOnActiveChanged; @@ -71,9 +73,24 @@ begin if Assigned(FOnActiveChanged) then FOnActiveChanged(FActiveIdx, Name, Active); end; -procedure TChannelController.ClearPreChannelPower; +procedure TChannelController.SetDriveGuarded(V: Integer); +// Drive, выставляемый самим юнитом (применение мощности канала / восстановление): +// rfDrive прилетит, но OnDriveChanged НЕ должен трактовать его как ручной → не +// сбрасывать FPreChannelPower. begin - FPreChannelPower := -1; + FRestoringDrive := True; + try + FRadio.SetDrive(V); + finally + FRestoringDrive := False; + end; +end; + +procedure TChannelController.OnDriveChanged; +// Вызывается из OnControllerState(rfDrive). Любое ВНЕШНЕЕ изменение drive +// (слайдер/web/энкодер) снимает сохранённую «до канала» мощность. +begin + if not FRestoringDrive then FPreChannelPower := -1; end; procedure TChannelController.Select(Idx: Integer); @@ -144,7 +161,7 @@ begin begin if FPreChannelPower < 0 then FPreChannelPower := FRadio.FDrivePercent; - FRadio.SetDrive(EnsureRange(Ch.Power, 0, 100)); + SetDriveGuarded(EnsureRange(Ch.Power, 0, 100)); end; // Частота VFO A (XVTR-клэмп, CTUN, band-detect, сеть — всё в SetVfoA) @@ -189,7 +206,7 @@ begin // Восстанавливаем мощность которая была до применения канала if FPreChannelPower >= 0 then begin - FRadio.SetDrive(FPreChannelPower); + SetDriveGuarded(FPreChannelPower); FPreChannelPower := -1; end; end; @@ -209,7 +226,7 @@ begin end; if FPreChannelPower >= 0 then begin - FRadio.SetDrive(FPreChannelPower); // восстановить + push + рендер слайдера + SetDriveGuarded(FPreChannelPower); // восстановить + push + рендер слайдера FPreChannelPower := -1; end; end; diff --git a/MainForm.pas b/MainForm.pas index b04cfa1..3776e35 100644 --- a/MainForm.pas +++ b/MainForm.pas @@ -441,7 +441,6 @@ type procedure WebOnBand(Idx: Integer); procedure WebOnSpan(Hz: Integer); procedure WebOnRun(On_: Boolean); - procedure WebOnDrive(V: Integer); procedure WebOnFreqA(Hz: Double); procedure WebOnXvtrBand(Idx: Integer); // Discovery / connect / saved-CRUD из web (маршалятся в UI) @@ -464,7 +463,6 @@ type procedure SyncWebXvtrBand; procedure SyncWebSpan; procedure SyncWebRun; - procedure SyncWebDrive; procedure SyncWebFreqA; // --- CAT callbacks ------------------------------------------------------- function CATGetVfoA: Double; @@ -982,7 +980,7 @@ begin FWebServer.OnBand := WebOnBand; FWebServer.OnSpan := WebOnSpan; FWebServer.OnRun := WebOnRun; - FWebServer.OnDrive := WebOnDrive; + FWebServer.OnDrive := FWebAdapter.OnDrive; FWebServer.OnFreqA := WebOnFreqA; FWebServer.OnWebMic := FWebAdapter.OnMic; FWebServer.OnXvtrBand := WebOnXvtrBand; @@ -1351,7 +1349,10 @@ begin rfVolume: TrkVolume.Position := FController.FVolume; rfDrive: - TrkDrive.Position := FController.FDrivePercent; // слайдер ← drive% + begin + TrkDrive.Position := FController.FDrivePercent; // слайдер ← drive% + FChannelController.OnDriveChanged; // внешнее изменение снимает память канала + end; rfAGCTop: begin TrkAGC.Position := FController.FAGCTop; @@ -5063,19 +5064,6 @@ end; // ── CTUN ────────────────────────────────────────────────────────────────── -procedure TMainForm.WebOnDrive(V: Integer); -begin - FWebSyncInt := V; - FWebSyncM := SyncWebDrive; - TThread.Synchronize(nil, FWebSyncM); -end; - -procedure TMainForm.SyncWebDrive; -begin - // Установка Position вызывает TrkDriveChange через OnChange автоматически - TrkDrive.Position := FWebSyncInt; -end; - procedure TMainForm.WebOnFreqA(Hz: Double); begin FWebSyncFreq := Hz; @@ -5091,8 +5079,7 @@ end; procedure TMainForm.TrkDriveChange(Sender: TObject); begin if FSyncingFromController then Exit; // программная установка из OnControllerState — не команда - FChannelController.ClearPreChannelPower; // ручное изменение снимает сохранённую мощность канала - FController.SetDrive(TrkDrive.Position); + FController.SetDrive(TrkDrive.Position); // rfDrive-рендер снимет память канала (OnDriveChanged) end; function TMainForm.CalcDriveByte: Byte; @@ -5859,7 +5846,7 @@ begin Ctx.SetActiveVfo := FWebAdapter.OnActiveVfo; Ctx.SetAGCMode := FWebAdapter.OnAGC; Ctx.SetVolume := FWebAdapter.OnVolume; - Ctx.SetDriveLevel := WebOnDrive; + Ctx.SetDriveLevel := FWebAdapter.OnDrive; Ctx.SetFilterIdx := CATSetFilterIdx; Ctx.SetNRMode := FWebAdapter.OnNR; Ctx.SetNBMode := FWebAdapter.OnNB; diff --git a/WebAdapter.pas b/WebAdapter.pas index 500ba32..5508fdb 100644 --- a/WebAdapter.pas +++ b/WebAdapter.pas @@ -45,6 +45,7 @@ type procedure SyncAGC; procedure SyncAGCTop; procedure SyncVolume; + procedure SyncDrive; procedure SyncWfAGC; procedure SyncWfNF; procedure SyncMute; @@ -70,6 +71,7 @@ type procedure OnAGC(Mode: Integer); procedure OnAGCTop(DB: Integer); procedure OnVolume(V: Integer); + procedure OnDrive(V: Integer); procedure OnWfAGC(On_: Boolean); procedure OnWfNF(On_: Boolean); procedure OnMute(On_: Boolean); @@ -145,6 +147,12 @@ begin FSyncInt := V; FController.Invoke(@SyncVolume); end; procedure TWebAdapter.SyncVolume; begin FController.SetVolume(FSyncInt); end; +procedure TWebAdapter.OnDrive(V: Integer); +begin FSyncInt := V; FController.Invoke(@SyncDrive); end; + +procedure TWebAdapter.SyncDrive; +begin FController.SetDrive(FSyncInt); end; // rfDrive снимет память канала (ChannelController) + procedure TWebAdapter.OnWfAGC(On_: Boolean); begin FSyncBool := On_; FController.Invoke(@SyncWfAGC); end;