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 -2
View File
@@ -29,7 +29,7 @@ uses
LCLIntf, LCLType, IntfGraphics, fpImage, AppTheme, PlatformUtils;
type
TPanZoomEvent = procedure(AZoom, APan: Double) of object;
TPanZoomEvent = procedure(Sender: TObject; AZoom, APan: Double) of object;
TDragMode = (dmNone, dmBody, dmLeft, dmRight);
@@ -196,7 +196,7 @@ begin
// Локально обновляем сразу — драг плавный даже до round-trip контроллера.
FZoom := Z; FPan := P;
if Assigned(FPb) then FPb.Invalidate;
if Assigned(FOnZoomPan) then FOnZoomPan(Z, P);
if Assigned(FOnZoomPan) then FOnZoomPan(Self, Z, P);
end;
procedure TPanZoomBar.DrawRulerInto(W, H: Integer);