mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 20:37:33 +00:00
Phase 3 (batch 9): route FM repeater shift through controller commands
FM Rpt is the first FM-Rpt heavy-class item (XvtrTranslate/ActiveTXFreqHz
blocker already lifted in d895800). Following the established pattern:
- TRadioController.SetFMRpt(Dir): explicit direction, clears auto-active,
pushes network state; rendered via OnControllerState(rfFMRpt).
- SetFMRptOffset(Hz): updates offset, re-pushes when RPT engaged.
- UpdateRptAutoState: 2 m auto-MINUS logic moved into controller, fires
Changed(rfFMRpt) instead of inline StyleButton.
- Extracted private PushNetworkState helper (full HP frame); SetCTun now
reuses it (dedupes the UpdateState+SendFullHP block).
MainForm: Btn/EdFMRpt handlers are thin wrappers (toggle decision +
SaveCurrentBand stay in UI); UpdateRptAutoState delegates to controller;
ApplyFMRpt removed. OnControllerState(rfFMRpt) restyles both buttons and
sets the offset edit text only when unfocused (avoids disrupting typing).
Direct FFMRptDir writes in band/channel/xvtr restore paths left as-is
(migrate with their own commands later). Builds clean.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
f12d2a69ad
commit
967e7cb7b1
+28
-63
@@ -433,7 +433,6 @@ type
|
|||||||
procedure BtnFMRptMinusClick(Sender: TObject);
|
procedure BtnFMRptMinusClick(Sender: TObject);
|
||||||
procedure BtnFMRptPlusClick(Sender: TObject);
|
procedure BtnFMRptPlusClick(Sender: TObject);
|
||||||
procedure EdFMRptOffsetChange(Sender: TObject);
|
procedure EdFMRptOffsetChange(Sender: TObject);
|
||||||
procedure ApplyFMRpt;
|
|
||||||
procedure UpdateRptAutoState;
|
procedure UpdateRptAutoState;
|
||||||
procedure SetFMStep(Idx: Integer);
|
procedure SetFMStep(Idx: Integer);
|
||||||
procedure CloseFMStepPopup;
|
procedure CloseFMStepPopup;
|
||||||
@@ -1468,6 +1467,22 @@ begin
|
|||||||
end;
|
end;
|
||||||
rfFMCTCSSTone:
|
rfFMCTCSSTone:
|
||||||
if FCTCSSDropDown <> nil then FCTCSSDropDown.SetItemIndex(FController.FFMCTCSSToneIdx);
|
if FCTCSSDropDown <> nil then FCTCSSDropDown.SetItemIndex(FController.FFMCTCSSToneIdx);
|
||||||
|
rfFMRpt:
|
||||||
|
begin
|
||||||
|
if BtnFMRptMinus <> nil then
|
||||||
|
begin
|
||||||
|
StyleButton(BtnFMRptMinus, FController.FFMRptDir = RPT_MINUS);
|
||||||
|
BtnFMRptMinus.Repaint;
|
||||||
|
end;
|
||||||
|
if BtnFMRptPlus <> nil then
|
||||||
|
begin
|
||||||
|
StyleButton(BtnFMRptPlus, FController.FFMRptDir = RPT_PLUS);
|
||||||
|
BtnFMRptPlus.Repaint;
|
||||||
|
end;
|
||||||
|
// Текст оффсета не трогаем, пока пользователь печатает в поле.
|
||||||
|
if (EdFMRptOffset <> nil) and not EdFMRptOffset.Focused then
|
||||||
|
EdFMRptOffset.Text := RptFormatOffset(FController.FFMRptOffsetHz);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
finally
|
finally
|
||||||
FSyncingFromController := False;
|
FSyncingFromController := False;
|
||||||
@@ -5241,91 +5256,41 @@ end;
|
|||||||
|
|
||||||
procedure TMainForm.BtnFMRptMinusClick(Sender: TObject);
|
procedure TMainForm.BtnFMRptMinusClick(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
|
if FSyncingFromController then Exit;
|
||||||
|
// Toggle решает UI; команда несёт сетевой сдвиг + рендер кнопок (OnControllerState).
|
||||||
if FController.FFMRptDir = RPT_MINUS then
|
if FController.FFMRptDir = RPT_MINUS then
|
||||||
FController.FFMRptDir := RPT_NONE
|
FController.SetFMRpt(RPT_NONE)
|
||||||
else
|
else
|
||||||
FController.FFMRptDir := RPT_MINUS;
|
FController.SetFMRpt(RPT_MINUS);
|
||||||
FController.FFMRptAutoActive := False; // ручное действие снимает авто-флаг
|
|
||||||
StyleButton(BtnFMRptMinus, FController.FFMRptDir = RPT_MINUS);
|
|
||||||
StyleButton(BtnFMRptPlus, FController.FFMRptDir = RPT_PLUS);
|
|
||||||
BtnFMRptMinus.Repaint;
|
|
||||||
BtnFMRptPlus.Repaint;
|
|
||||||
ApplyFMRpt;
|
|
||||||
SaveCurrentBand;
|
SaveCurrentBand;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMainForm.BtnFMRptPlusClick(Sender: TObject);
|
procedure TMainForm.BtnFMRptPlusClick(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
|
if FSyncingFromController then Exit;
|
||||||
if FController.FFMRptDir = RPT_PLUS then
|
if FController.FFMRptDir = RPT_PLUS then
|
||||||
FController.FFMRptDir := RPT_NONE
|
FController.SetFMRpt(RPT_NONE)
|
||||||
else
|
else
|
||||||
FController.FFMRptDir := RPT_PLUS;
|
FController.SetFMRpt(RPT_PLUS);
|
||||||
FController.FFMRptAutoActive := False; // ручное действие снимает авто-флаг
|
|
||||||
StyleButton(BtnFMRptMinus, FController.FFMRptDir = RPT_MINUS);
|
|
||||||
StyleButton(BtnFMRptPlus, FController.FFMRptDir = RPT_PLUS);
|
|
||||||
BtnFMRptMinus.Repaint;
|
|
||||||
BtnFMRptPlus.Repaint;
|
|
||||||
ApplyFMRpt;
|
|
||||||
SaveCurrentBand;
|
SaveCurrentBand;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMainForm.EdFMRptOffsetChange(Sender: TObject);
|
procedure TMainForm.EdFMRptOffsetChange(Sender: TObject);
|
||||||
var Hz: Double;
|
var Hz: Double;
|
||||||
begin
|
begin
|
||||||
|
if FSyncingFromController then Exit;
|
||||||
Hz := RptParseOffset(EdFMRptOffset.Text);
|
Hz := RptParseOffset(EdFMRptOffset.Text);
|
||||||
if Hz > 0.0 then
|
if Hz > 0.0 then
|
||||||
begin
|
begin
|
||||||
FController.FFMRptOffsetHz := Hz;
|
FController.SetFMRptOffset(Hz); // применяет, если RPT вкл; OnControllerState
|
||||||
if FController.FFMRptDir <> RPT_NONE then
|
if FController.FFMRptDir <> RPT_NONE then SaveCurrentBand;
|
||||||
begin
|
|
||||||
ApplyFMRpt;
|
|
||||||
SaveCurrentBand;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TMainForm.ApplyFMRpt;
|
|
||||||
begin
|
|
||||||
if FController.FNetwork.Connected and FController.FNetwork.Running then
|
|
||||||
begin
|
|
||||||
FController.FNetwork.UpdateState(XvtrTranslate(FController.FCenterFreq), XvtrTranslate(ActiveTXFreqHz),
|
|
||||||
FController.FDriveLevel, FController.FTransmitting, True, True);
|
|
||||||
FController.FNetwork.SendFullHP;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMainForm.UpdateRptAutoState;
|
procedure TMainForm.UpdateRptAutoState;
|
||||||
var InRange: Boolean;
|
|
||||||
begin
|
begin
|
||||||
InRange := RptAutoDir(FController.FVfoA) = RPT_MINUS;
|
// Логика авто-MINUS — в контроллере; рендер кнопок — OnControllerState(rfFMRpt).
|
||||||
if InRange then
|
FController.UpdateRptAutoState;
|
||||||
begin
|
|
||||||
// Auto-enable minus only when currently off.
|
|
||||||
if FController.FFMRptDir = RPT_NONE then
|
|
||||||
begin
|
|
||||||
FController.FFMRptDir := RPT_MINUS;
|
|
||||||
FController.FFMRptAutoActive := True;
|
|
||||||
if BtnFMRptMinus <> nil then
|
|
||||||
begin
|
|
||||||
StyleButton(BtnFMRptMinus, True);
|
|
||||||
BtnFMRptMinus.Repaint;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
// Auto-disable only if this minus was set automatically.
|
|
||||||
if (FController.FFMRptDir = RPT_MINUS) and FController.FFMRptAutoActive then
|
|
||||||
begin
|
|
||||||
FController.FFMRptDir := RPT_NONE;
|
|
||||||
FController.FFMRptAutoActive := False;
|
|
||||||
if BtnFMRptMinus <> nil then
|
|
||||||
begin
|
|
||||||
StyleButton(BtnFMRptMinus, False);
|
|
||||||
BtnFMRptMinus.Repaint;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMainForm.CloseFMStepPopup;
|
procedure TMainForm.CloseFMStepPopup;
|
||||||
|
|||||||
+55
-8
@@ -110,6 +110,7 @@ type
|
|||||||
procedure Changed(Field: TRadioField);
|
procedure Changed(Field: TRadioField);
|
||||||
procedure ApplyAGCToEngine; // применяет FAGCMode к WDSP (единый маппинг)
|
procedure ApplyAGCToEngine; // применяет FAGCMode к WDSP (единый маппинг)
|
||||||
procedure ApplyModeDefaults; // дефолтный фильтр/девиация под текущий FMode
|
procedure ApplyModeDefaults; // дефолтный фильтр/девиация под текущий FMode
|
||||||
|
procedure PushNetworkState; // полный HP-кадр в радио (RX/TX freq+drive)
|
||||||
public
|
public
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// ПУБЛИЧНЫЕ ПОЛЯ (миграционные — имена совпадают с TMainForm).
|
// ПУБЛИЧНЫЕ ПОЛЯ (миграционные — имена совпадают с TMainForm).
|
||||||
@@ -277,7 +278,9 @@ type
|
|||||||
procedure SetFMCTCSSTone(Idx: Integer);
|
procedure SetFMCTCSSTone(Idx: Integer);
|
||||||
procedure SetFMSquelch(On_: Boolean);
|
procedure SetFMSquelch(On_: Boolean);
|
||||||
procedure SetFMSquelchLevel(V: Integer);
|
procedure SetFMSquelchLevel(V: Integer);
|
||||||
procedure SetFMRpt(Dir: Integer);
|
procedure SetFMRpt(Dir: Integer); // явное направление; снимает авто-флаг
|
||||||
|
procedure SetFMRptOffset(Hz: Double); // сдвиг репитера; применяет, если RPT вкл
|
||||||
|
procedure UpdateRptAutoState; // авто-MINUS для 2 м под FVfoA
|
||||||
|
|
||||||
// Каналы
|
// Каналы
|
||||||
procedure ApplyChannel(Idx: Integer);
|
procedure ApplyChannel(Idx: Integer);
|
||||||
@@ -323,6 +326,18 @@ begin
|
|||||||
if Assigned(FOnStateChanged) then FOnStateChanged(Self, Field);
|
if Assigned(FOnStateChanged) then FOnStateChanged(Self, Field);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TRadioController.PushNetworkState;
|
||||||
|
// Полный HP-кадр в радио: RX/TX частоты (через трансвертор), drive, состояние
|
||||||
|
// MOX. Вызывается командами, которые меняют центр/частоту/репитер-сдвиг.
|
||||||
|
begin
|
||||||
|
if Assigned(FNetwork) and FNetwork.Connected and FNetwork.Running then
|
||||||
|
begin
|
||||||
|
FNetwork.UpdateState(XvtrTranslate(FCenterFreq), XvtrTranslate(ActiveTXFreqHz),
|
||||||
|
FDriveLevel, FTransmitting, True, True);
|
||||||
|
FNetwork.SendFullHP;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TRadioController.Invoke(M: TThreadMethod);
|
procedure TRadioController.Invoke(M: TThreadMethod);
|
||||||
begin
|
begin
|
||||||
if Assigned(FOnInvoke) then FOnInvoke(M)
|
if Assigned(FOnInvoke) then FOnInvoke(M)
|
||||||
@@ -586,12 +601,7 @@ begin
|
|||||||
// движок — FCenterFreq остаётся как есть, спектр не прыгает.)
|
// движок — FCenterFreq остаётся как есть, спектр не прыгает.)
|
||||||
FCenterFreq := FVfoA;
|
FCenterFreq := FVfoA;
|
||||||
if FWDSPReady and Assigned(FDSPEngine) then FDSPEngine.SetShift(0.0);
|
if FWDSPReady and Assigned(FDSPEngine) then FDSPEngine.SetShift(0.0);
|
||||||
if Assigned(FNetwork) and FNetwork.Connected and FNetwork.Running then
|
PushNetworkState;
|
||||||
begin
|
|
||||||
FNetwork.UpdateState(XvtrTranslate(FCenterFreq), XvtrTranslate(ActiveTXFreqHz),
|
|
||||||
FDriveLevel, FTransmitting, True, True);
|
|
||||||
FNetwork.SendFullHP;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
Changed(rfCTun);
|
Changed(rfCTun);
|
||||||
end;
|
end;
|
||||||
@@ -682,7 +692,44 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TRadioController.SetFMRpt(Dir: Integer);
|
procedure TRadioController.SetFMRpt(Dir: Integer);
|
||||||
begin FFMRptDir := Dir; Changed(rfFMRpt); { TODO wiring } end;
|
begin
|
||||||
|
FFMRptDir := Dir;
|
||||||
|
FFMRptAutoActive := False; // явная установка направления — ручное действие
|
||||||
|
PushNetworkState; // TX-сдвиг применяется через ActiveTXFreqHz
|
||||||
|
Changed(rfFMRpt);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TRadioController.SetFMRptOffset(Hz: Double);
|
||||||
|
begin
|
||||||
|
if Hz <= 0.0 then Exit;
|
||||||
|
FFMRptOffsetHz := Hz;
|
||||||
|
if FFMRptDir <> RPT_NONE then PushNetworkState;
|
||||||
|
Changed(rfFMRpt);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TRadioController.UpdateRptAutoState;
|
||||||
|
// Авто-включение MINUS-сдвига в 2-метровом репитерном сегменте и авто-снятие
|
||||||
|
// при уходе из него (только если MINUS был выставлен автоматически).
|
||||||
|
begin
|
||||||
|
if RptAutoDir(FVfoA) = RPT_MINUS then
|
||||||
|
begin
|
||||||
|
if FFMRptDir = RPT_NONE then
|
||||||
|
begin
|
||||||
|
FFMRptDir := RPT_MINUS;
|
||||||
|
FFMRptAutoActive := True;
|
||||||
|
Changed(rfFMRpt);
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
if (FFMRptDir = RPT_MINUS) and FFMRptAutoActive then
|
||||||
|
begin
|
||||||
|
FFMRptDir := RPT_NONE;
|
||||||
|
FFMRptAutoActive := False;
|
||||||
|
Changed(rfFMRpt);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TRadioController.ApplyChannel(Idx: Integer);
|
procedure TRadioController.ApplyChannel(Idx: Integer);
|
||||||
begin Changed(rfChannel); { TODO wiring } end;
|
begin Changed(rfChannel); { TODO wiring } end;
|
||||||
|
|||||||
Reference in New Issue
Block a user