feat(slices): пан-зум панов N — свой бар/кнопки, span-clip анализатора пана

Движок: TPanChan.ZoomFactor/PanSlider, span-clip в ApplyPanAnalyzerSettings
(математика главного, ZOOM_LIMIT 100), SetPanZoomPan с no-op guard (SetAnalyzer
сбрасывает FFT-историю). Зум переживает смену rate/ADC пана.
Контроллер: формула окна вынесена в ViewWindowFor (главный GetViewWindow тоже
через неё), GetPanViewWindow (PanId=0 делегирует), PanZoomIn/Out по лестнице
кратностей с якорем на центре окна, PanZoomDefault, геттеры.
UI: TPanZoomEvent получил Sender; у панов N включён ряд зума, бар
диспетчеризуется по объекту, кнопки −/⌂/+ общие через PanOfZoomButton (матч по
идентичности — MakeFlatBtn создаёт кнопки с Owner=контейнер, PanFromSender их
не видит); SyncPanZoomUI/RefreshPanZoom, вся мышь панов зум-корректна через
GetPanViewWindow. Темизация баров панов N.
Смоук panzoomtest ALL PASS (пик тона совпадает с формулой окна ±0.6%),
подтверждено на экране.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-12 11:35:13 +03:00
co-authored by Claude Fable 5
parent 209e490dfa
commit 64edf9e289
6 changed files with 312 additions and 36 deletions
+2 -7
View File
@@ -512,13 +512,8 @@ procedure TPanafallPanel.ViewWindow(out VC, VS: Double);
begin
VC := 0; VS := 0;
if FController = nil then Exit;
if FPanId = 0 then
FController.GetViewWindow(VC, VS)
else
begin
VC := FController.PanDDCFreq(FPanId);
VS := FController.PanDDCRateKHz(FPanId) * 1000.0;
end;
// Единая точка видимого окна: PanId=0 → главный зум, паны N → свой пан-зум.
FController.GetPanViewWindow(FPanId, VC, VS);
end;
procedure TPanafallPanel.PositionHeaderChildren(RW, H: Integer);