Fix VfoOverlay FM mode: NFM/FM filters, deviation sync, button layout

- FM filter row now shows only NFM (11 kHz) and FM (16 kHz) matching MainForm
- OnModeFilterSelect updates FFMDeviation and FFilter index for FM mode
- Mode and filter button widths distributed evenly (proportional, not fixed BtnW)
- S-meter inset by extra 4 px on each side

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-22 12:32:33 +03:00
co-authored by Claude Sonnet 4.6
parent d99c19ec9a
commit 5a74017e8a
2 changed files with 37 additions and 21 deletions
+13
View File
@@ -5519,9 +5519,22 @@ begin
end; end;
procedure TMainForm.OnModeFilterSelect(Mode: Integer; FilterBW: Integer); procedure TMainForm.OnModeFilterSelect(Mode: Integer; FilterBW: Integer);
var
Idx: Integer;
begin begin
FMode := Mode; FMode := Mode;
FFilterBW := FilterBW; FFilterBW := FilterBW;
if Mode = MODE_FM then
begin
FFilter := FILT_FM_DEF;
for Idx := 0 to FILT_FM_COUNT - 1 do
if FILT_FM_BW[Idx] = FilterBW then
begin
FFilter := Idx;
FFMDeviation := FILT_FM_DEV[Idx];
Break;
end;
end;
if FWDSPReady then if FWDSPReady then
begin begin
FDSPEngine.SetMode(FMode); FDSPEngine.SetMode(FMode);
+24 -21
View File
@@ -85,9 +85,9 @@ const
CW_BW: array[0..5] of Integer = (500,250,150,100,50,1000); CW_BW: array[0..5] of Integer = (500,250,150,100,50,1000);
CW_LBL: array[0..5] of string = ('500','250','150','100','50','1K'); CW_LBL: array[0..5] of string = ('500','250','150','100','50','1K');
// Фильтры FM (FM=5) // Фильтры FM (FM=5) — только NFM и FM, как в MainForm
FM_BW: array[0..5] of Integer = (20000,15000,12000,10000,8000,5000); FM_BW: array[0..1] of Integer = (11000, 16000);
FM_LBL: array[0..5] of string = ('20K','15K','12K','10K','8K','5K'); FM_LBL: array[0..1] of string = ('NFM', 'FM');
// Фильтры AM/SAM (AM=6, SAM=7) // Фильтры AM/SAM (AM=6, SAM=7)
AM_BW: array[0..5] of Integer = (20000,16000,12000,10000,8000,6000); AM_BW: array[0..5] of Integer = (20000,16000,12000,10000,8000,6000);
@@ -120,7 +120,8 @@ end;
function TVfoOverlay.GetFilterCountForMode(ModeIdx: Integer): Integer; function TVfoOverlay.GetFilterCountForMode(ModeIdx: Integer): Integer;
begin begin
Result := 6; // всегда 6 вариантов фильтра if ModeIdx = 5 then Result := 2 // FM: только NFM и FM
else Result := 6;
end; end;
function DBmToSLabel(DB: Double): string; function DBmToSLabel(DB: Double): string;
@@ -166,7 +167,7 @@ begin
FModeFilter[2] := 8000; // DSB FModeFilter[2] := 8000; // DSB
FModeFilter[3] := 500; // CWL FModeFilter[3] := 500; // CWL
FModeFilter[4] := 500; // CWU FModeFilter[4] := 500; // CWU
FModeFilter[5] := 15000; // FM FModeFilter[5] := 11000; // FM (NFM по умолчанию)
FModeFilter[6] := 8000; // AM FModeFilter[6] := 8000; // AM
FModeFilter[7] := 8000; // SAM FModeFilter[7] := 8000; // SAM
Width := 260; // шире — 8 кнопок режимов Width := 260; // шире — 8 кнопок режимов
@@ -262,17 +263,17 @@ end;
procedure TVfoOverlay.DrawModeRow(C: TCanvas; X, Y, RowW, RowH: Integer); procedure TVfoOverlay.DrawModeRow(C: TCanvas; X, Y, RowW, RowH: Integer);
var var
I, BtnW, BX: Integer; I, BX, BRight: Integer;
HR: TRect; HR: TRect;
IsAct, IsHot: Boolean; IsAct, IsHot: Boolean;
begin begin
BtnW := (RowW - (OVL_MODE_COUNT - 1)) div OVL_MODE_COUNT; BX := X;
for I := 0 to OVL_MODE_COUNT - 1 do for I := 0 to OVL_MODE_COUNT - 1 do
begin begin
BX := X + I * (BtnW + 1); BRight := X + ((I + 1) * RowW) div OVL_MODE_COUNT;
HR := Rect(BX, Y, BX + BtnW, Y + RowH); HR := Rect(BX, Y, BRight, Y + RowH);
IsAct := (I = FMode); IsAct := (I = FMode);
IsHot := (FHotIdx >= 0) and (FHitActions[FHotIdx] = -(I + 1)); IsHot := (FHotIdx >= 0) and (FHitActions[FHotIdx] = -(I + 1));
if IsAct then C.Brush.Color := CLR_BTN_ACT if IsAct then C.Brush.Color := CLR_BTN_ACT
else if IsHot then C.Brush.Color := CLR_BTN_HOT else if IsHot then C.Brush.Color := CLR_BTN_HOT
@@ -286,29 +287,30 @@ begin
else C.Font.Color := CLR_TEXT; else C.Font.Color := CLR_TEXT;
C.Font.Size := 6; C.Font.Style := []; C.Font.Name := 'Courier New'; C.Font.Size := 6; C.Font.Style := []; C.Font.Name := 'Courier New';
C.Brush.Style := bsClear; C.Brush.Style := bsClear;
C.TextOut(BX + (BtnW - C.TextWidth(OVL_MODE_NAMES[I])) div 2, C.TextOut(BX + (BRight - BX - C.TextWidth(OVL_MODE_NAMES[I])) div 2,
Y + (RowH - C.TextHeight('A')) div 2, Y + (RowH - C.TextHeight('A')) div 2,
OVL_MODE_NAMES[I]); OVL_MODE_NAMES[I]);
RegisterHit(HR, -(I + 1)); // -1=LSB, -2=USB, -3=DSB, -4=CWL, -5=CWU, -6=FM, -7=AM, -8=SAM RegisterHit(HR, -(I + 1)); // -1=LSB, -2=USB, -3=DSB, -4=CWL, -5=CWU, -6=FM, -7=AM, -8=SAM
BX := BRight + 1;
end; end;
end; end;
procedure TVfoOverlay.DrawFilterRow(C: TCanvas; X, Y, RowW, RowH: Integer); procedure TVfoOverlay.DrawFilterRow(C: TCanvas; X, Y, RowW, RowH: Integer);
const
FILT_COUNT = 6;
var var
I, BtnW, BX, BV: Integer; FILT_COUNT: Integer;
I, BX, BRight, BV: Integer;
HR: TRect; HR: TRect;
Lbl: string; Lbl: string;
IsAct: Boolean; IsAct: Boolean;
begin begin
BtnW := (RowW - (FILT_COUNT - 1)) div FILT_COUNT; FILT_COUNT := GetFilterCountForMode(FMode);
BX := X;
for I := 0 to FILT_COUNT - 1 do for I := 0 to FILT_COUNT - 1 do
begin begin
BX := X + I * (BtnW + 1); BRight := X + ((I + 1) * RowW) div FILT_COUNT;
HR := Rect(BX, Y, BX + BtnW, Y + RowH); HR := Rect(BX, Y, BRight, Y + RowH);
BV := GetFilterBWForMode(FMode, I); BV := GetFilterBWForMode(FMode, I);
IsAct := (BV = FFilterBW); IsAct := (BV = FFilterBW);
Lbl := GetFilterLblForMode(FMode, I); Lbl := GetFilterLblForMode(FMode, I);
@@ -325,10 +327,11 @@ begin
else C.Font.Color := CLR_TEXT; else C.Font.Color := CLR_TEXT;
C.Font.Size := 7; C.Font.Name := 'Courier New'; C.Font.Size := 7; C.Font.Name := 'Courier New';
C.Brush.Style := bsClear; C.Brush.Style := bsClear;
C.TextOut(BX + (BtnW - C.TextWidth(Lbl)) div 2, C.TextOut(BX + (BRight - BX - C.TextWidth(Lbl)) div 2,
Y + (RowH - C.TextHeight('A')) div 2, Lbl); Y + (RowH - C.TextHeight('A')) div 2, Lbl);
RegisterHit(HR, BV); // BV всегда > 0 (BW в Гц, минимум 25) RegisterHit(HR, BV); // BV всегда > 0 (BW в Гц, минимум 25)
BX := BRight + 1;
end; end;
end; end;
@@ -374,7 +377,7 @@ begin
Inc(CurY, INFO_H); Inc(CurY, INFO_H);
// S-метр // S-метр
DrawSMeterBar(C, PAD, CurY, W - PAD * 2, SM_H); DrawSMeterBar(C, PAD + 4, CurY, W - (PAD + 4) * 2, SM_H);
Inc(CurY, SM_H + GAP); Inc(CurY, SM_H + GAP);
// Кнопки режимов // Кнопки режимов