mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 20:37:33 +00:00
feat(filter): произвольные кромки фильтра — таблица по режиму, редактор, drag, TX-полоска
Фильтр главного приёмника перестал быть одним числом. Теперь это таблица (Name, Low, High) на режим: 10 пресетов + VAR1/VAR2, знаковые кромки (у LSB своя строка, у USB своя), паритет с Thetis FilterForm. Слайсы независимые кромки умели и раньше — главный приёмник настраивался только пресетами. Модель (Settings/RadioController): - TFilterSlot/TFilterSet/TFilterTable + заводские дефолты из прежних FILT_*_BW и FILT_*_NAMES (переехали в Settings — из них строится таблица). - FFilterLo/FFilterHi = истина, FFilterBW производная (FilterBWFromEdges), поэтому все прежние читатели ширины (web, зум, band-cache, CAT) не тронуты. - ApplyFilterSlot — единственная точка «слот → состояние тракта». - SetFilterEdges: произвольные кромки уходят в VAR1 с автопереключением, пресеты нельзя испортить случайным движением мыши или энкодера. - Персист: секция "filters" под MAC, пишутся только режимы, отличные от заводских; секция режима сносится целиком, иначе возврат слота к заводскому оставлял бы старый ключ. - Диапазон помнит только выбранный слот: кромки живут в таблице, второго источника истины у VAR нет. UI: - 12 кнопок фильтра (2 ряда по 6), подписи из живой таблицы. - FilterPopup — поповер редактора по ПКМ на кнопке фильтра, по образцу PureSignalPopup (дочерний контрол формы, не top-level: Wayland). Слева слоты, справа Name/Low/High/Width, внизу форма полосы на знаковой оси. - Перетаскивание края полосы на спектре: ±5px, снап 10 Гц, Alt = симметрично (не Ctrl — он создаёт слайс). Отказ на передаче и когда полоса на экране уже 12px, иначе захват съедал бы клик-тюн. Отрисовка: - Полоса главного VFO рисуется по РЕАЛЬНЫМ кромкам приёмника, слайса — по его кромкам; вывод из режима и ширины остался фолбэком. Пара→ширина→пара было преобразованием с потерями: несимметричный фильтр из слайс-CAT (ZZFL/ZZFH) рисовался не там, где звучал. - На передаче полоса считается по TX-фильтру (TXSignedEdges), а не по приёмной ширине — TX-полоса от RX не зависит (модель Thetis). - CalcFilterBandXFor больше не держит свою копию таблицы знака боковой: единственная таблица теперь FilterEdgesFromBW. Управление: - CAT ZZFL/ZZFH заработали на основном порту (были заглушками). - Андромеда: энкодеры #4/#5 — независимые Filter High/Low, как на железе G2 (было: #4 ширина, #5 не реализован). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -49,6 +49,10 @@ type
|
||||
function GetDriveLevel: Integer;
|
||||
function GetFilterIdx: Integer;
|
||||
function GetFilterBW: Integer;
|
||||
function GetFilterLow: Integer;
|
||||
function GetFilterHigh: Integer;
|
||||
procedure SetFilterLow(V: Integer);
|
||||
procedure SetFilterHigh(V: Integer);
|
||||
function GetNRMode: Integer;
|
||||
function GetNBMode: Integer;
|
||||
function GetSNB: Boolean;
|
||||
@@ -161,6 +165,10 @@ begin
|
||||
Ctx.GetDriveLevel := @GetDriveLevel;
|
||||
Ctx.GetFilterIdx := @GetFilterIdx;
|
||||
Ctx.GetFilterBW := @GetFilterBW;
|
||||
// Кромки фильтра (ZZFL/ZZFH). Раньше у главного приёмника были nil (фильтр
|
||||
// был индексным) — теперь он хранит те же знаковые кромки, что и слайс.
|
||||
Ctx.GetFilterLow := @GetFilterLow;
|
||||
Ctx.GetFilterHigh := @GetFilterHigh;
|
||||
Ctx.GetNRMode := @GetNRMode;
|
||||
Ctx.GetNBMode := @GetNBMode;
|
||||
Ctx.GetSNBEnabled := @GetSNB;
|
||||
@@ -177,6 +185,8 @@ begin
|
||||
Ctx.SetVolume := @SetVolume;
|
||||
Ctx.SetDriveLevel := @SetDriveLevel;
|
||||
Ctx.SetFilterIdx := @SetFilterIdx;
|
||||
Ctx.SetFilterLow := @SetFilterLow;
|
||||
Ctx.SetFilterHigh := @SetFilterHigh;
|
||||
Ctx.SetNRMode := @SetNRMode;
|
||||
Ctx.SetNBMode := @SetNBMode;
|
||||
Ctx.SetSNBEnabled := @SetSNB;
|
||||
@@ -297,6 +307,14 @@ function TCATAdapter.GetVolume: Integer; begin Result := FController.FVolume
|
||||
function TCATAdapter.GetDriveLevel: Integer; begin Result := FController.FDrivePercent; end;
|
||||
function TCATAdapter.GetFilterIdx: Integer; begin Result := FController.FFilter; end;
|
||||
function TCATAdapter.GetFilterBW: Integer; begin Result := FController.FFilterBW; end;
|
||||
function TCATAdapter.GetFilterLow: Integer; begin Result := FController.FilterLo; end;
|
||||
function TCATAdapter.GetFilterHigh: Integer; begin Result := FController.FilterHi; end;
|
||||
// Кромку меняем по одной — вторую держим текущей (контроллер уводит правку в
|
||||
// VAR, поэтому пресеты внешняя программа не испортит).
|
||||
procedure TCATAdapter.SetFilterLow(V: Integer);
|
||||
begin FController.SetFilterEdges(V, FController.FilterHi); end;
|
||||
procedure TCATAdapter.SetFilterHigh(V: Integer);
|
||||
begin FController.SetFilterEdges(FController.FilterLo, V); end;
|
||||
function TCATAdapter.GetNRMode: Integer; begin Result := FController.FNRMode; end;
|
||||
function TCATAdapter.GetNBMode: Integer; begin Result := FController.FNBMode; end;
|
||||
function TCATAdapter.GetSNB: Boolean; begin Result := FController.FSNB; end;
|
||||
|
||||
Reference in New Issue
Block a user