mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 19:45:09 +00:00
feat(spectrum): zoom + pan для спектра и водопада (WDSP span-clip)
Зум через нативный span-clip WDSP (fscLin/fscHin в SetAnalyzer): clp=0, видимое окно сужается клипом, при зуме 0 полоса == sample rate (старое поведение сохранено). Конвенция как в Thetis: ZoomFactor 0=без зума..1=макс. - WDSPEngine: SetZoomPan + расчёт span-clip, ViewLowHz/ViewHighHz. - RadioController: GetViewWindow (единая истина видимого окна для оверлеев и мыши), ApplyZoom, ZoomIn/Out по лестнице кратностей, ZoomDefault. Якорь зума кнопками — на маркере активного VFO. rfZoom. - Per-band персист зума/пана (TBandSettings + Save/Load/Restore). - MainForm: маршрутизация оверлеев/кликов через GetViewWindow (покрывает CPU и OpenGL), резерв строки PANZOOM_H в layout + сплиттере, rfZoom-рендер. - WebAdapter: web-спектр/наведение на view-окно (делит те же WDSP-пиксели). - PanZoomBar (новый): нижняя полоса = линейка полного диапазона (частоты + деления), поверх окно-селектор «стекло» (полупрозрачное, объёмная фаска). Середина=пан, края=зум, клик мимо=центрировать, двойной клик=сброс. Сборка ewsdr (--ws=qt6) и ewsdrd — ОК. На железе не проверено. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -67,6 +67,8 @@ type
|
||||
FMStepIdx: Integer; // 0..3 (6.25/12.5/20/25 kHz)
|
||||
FMRptDir: Integer; // RPT_NONE/RPT_MINUS/RPT_PLUS
|
||||
FMRptOffsetHz: Double; // Hz, 0 = use band default
|
||||
ZoomFactor: Double; // зум спектра/водопада 0.0..1.0 (0.0 = без зума)
|
||||
PanSlider: Double; // положение окна зума 0..1 (0.5 = центр)
|
||||
end;
|
||||
|
||||
// TX-настройки per-device. Хранятся в JSON-секции "tx" под MAC,
|
||||
@@ -407,6 +409,8 @@ begin
|
||||
B.FMStepIdx := 3; // 25 kHz
|
||||
B.FMRptDir := 0;
|
||||
B.FMRptOffsetHz := 0.0;
|
||||
B.ZoomFactor := 0.0;
|
||||
B.PanSlider := 0.5;
|
||||
end;
|
||||
|
||||
class procedure TSettingsManager.DefaultGlobal(out G: TGlobalSettings);
|
||||
@@ -823,6 +827,7 @@ begin
|
||||
JW(O,'ctcss_on',B.CTCSSOn); JW(O,'ctcss_idx',B.CTCSSToneIdx);
|
||||
JW(O,'fmstep_on',B.FMStepOn); JW(O,'fmstep_idx',B.FMStepIdx);
|
||||
JW(O,'fmrpt_dir',B.FMRptDir); JW(O,'fmrpt_offset',B.FMRptOffsetHz);
|
||||
JW(O,'zoom_factor',B.ZoomFactor); JW(O,'pan_slider',B.PanSlider);
|
||||
end;
|
||||
|
||||
function TSettingsManager.LoadBand(const MAC: array of Byte; BandIdx: Integer;
|
||||
@@ -852,6 +857,8 @@ begin
|
||||
B.FMStepIdx := EnsureRange(JI(O,'fmstep_idx', B.FMStepIdx), 0, 3);
|
||||
B.FMRptDir := EnsureRange(JI(O,'fmrpt_dir', B.FMRptDir), 0, 2);
|
||||
B.FMRptOffsetHz := JD(O,'fmrpt_offset', B.FMRptOffsetHz);
|
||||
B.ZoomFactor := EnsureRange(JD(O,'zoom_factor', B.ZoomFactor), 0.0, 1.0);
|
||||
B.PanSlider := EnsureRange(JD(O,'pan_slider', B.PanSlider), 0.0, 1.0);
|
||||
end;
|
||||
|
||||
procedure TSettingsManager.SaveWindowBounds(L, T, W, H, DPI: Integer; Maximized: Boolean);
|
||||
|
||||
Reference in New Issue
Block a user