feat: QO-100 NB transponder bandplan overlay on spectrum

Add a thin colored strip along the bottom of the spectrum (above the
ruler) showing the QO-100 narrow-band transponder bandplan: mode
segments (CW ONLY / NB DIGI / DIGI / SSB / MIXED MODES) plus the three
beacons (CW / PSK / EXP) as muted-red cells at their ranges.

- New unit BandPlanOverlay.pas (TBandPlanOverlay), modelled on
  VfoOverlay: content rendered once into a cache bitmap, per-frame cost
  is just a constant-alpha composite (CPU) / one textured quad (GL).
  Cache invalidates only on view change (center/span/width) so it idles
  while the QO-100 downlink display is static.
- Wired into both render paths: SpectrumView (CPU composite) and
  SpectrumViewOpengl (texture, re-uploaded only when dirty).
- MainForm: SetView fed from SyncSpecViewFreq; visibility gated by
  InQO100 (Pluto + full-duplex transponder), like RX MUTE / BEACON.
- DPI-robust: strip height scales with Screen.PixelsPerInch and the font
  height is tied to the strip height (not point size), so labels always
  fit at any Windows scaling.
- Segment/beacon frequencies and colors are a single editable table.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-23 21:02:50 +03:00
co-authored by Claude Opus 4.8
parent 3bd37b956e
commit 432c0285f0
5 changed files with 382 additions and 6 deletions
+6 -1
View File
@@ -20,7 +20,7 @@ interface
uses
Classes, SysUtils, Graphics, ExtCtrls, Controls, Math,
AppTheme,
AlertOverlay, SampleRateOverlay, VfoOverlay,
AlertOverlay, SampleRateOverlay, VfoOverlay, BandPlanOverlay,
WaterfallView, SMeterView, RulerView;
const
@@ -70,6 +70,7 @@ type
FADCOverloadVisible: Boolean;
FSampleRateOverlay: TSampleRateOverlay;
FVfoOverlay: TVfoOverlay;
FBandPlanOverlay: TBandPlanOverlay;
// ── Marker ────────────────────────────────────────────────────────────────
FMarkerActive: Boolean;
FMarkerX: Integer;
@@ -217,6 +218,7 @@ type
property PbSMeterRight: TPaintBox write SetPbSMeterRight;
property SampleRateOverlay: TSampleRateOverlay read FSampleRateOverlay write FSampleRateOverlay;
property VfoOverlay: TVfoOverlay read FVfoOverlay write FVfoOverlay;
property BandPlanOverlay: TBandPlanOverlay read FBandPlanOverlay write FBandPlanOverlay;
// ── Данные от DSP ─────────────────────────────────────────────────────────
procedure SetSpectrumData(const Pixels: array of Single; Count: Integer); virtual;
@@ -1000,6 +1002,9 @@ begin
if FMarkerActive then DrawMarkerLine(C, W, H);
if FBeaconMarkActive or FBeaconDecActive then DrawBeaconMarkers(C, W, H);
DrawADCOverloadOverlay(C, W, H);
// Бэндплан QO-100 — полоска внизу спектра (над ruler), под панелями оверлеев.
if Assigned(FBandPlanOverlay) then
FBandPlanOverlay.DrawOverlay(FSpectrumBitmap, W, H);
if Assigned(FSampleRateOverlay) then
FSampleRateOverlay.DrawOverlay(FSpectrumBitmap, C, W, H);
if Assigned(FVfoOverlay) then