feat(slices): грид-раскладка панов + фиксы минимумов стека, утечки кнопок, CPU

Грид: пан 0 сверху во всю ширину, доп. паны колонками снизу; тумблер
«▦/▤» в ряду зума пана 0, вертикальные сплиттеры-призраки колонок
(FPanColShare), доля ряда FPanGridRowShare; автоткат в стек при <2 доп.
панах. Регион пана обобщён до прямоугольника (StackLeft/StackWidth).

Фиксы по экранному тесту:
- наезд панов: раздача высот и драг сплиттеров клампятся минимумом
  содержимого пана (MinLayoutHeight/PanMinHeight, пан 0 += wideband);
- «блуждающие» кнопки после STOP: MakeFlatBtn даёт Owner=контейнер,
  TPanafallPanel.Destroy теперь явно освобождает −/⌂/+/⊞/▦;
- жор CPU ~40%/пан: убран безусловный Invalidate зум-бара из тика
  (SyncPanZoomUI), инвалидация только при реальной смене значений;
- пропорция спектр/водопад пана 0 не восстанавливалась после закрытия
  панов: кламп ratio минимумами больше не пишется в FSplitterRatio.

Подтверждено юзером на экране: грид/стек/STOP/pop-out работают,
CPU со всеми панами 17-20%.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-12 15:51:11 +03:00
co-authored by Claude Fable 5
parent 64edf9e289
commit eac66100a8
3 changed files with 501 additions and 66 deletions
+71
View File
@@ -573,6 +573,77 @@ RATEPROBE удалены.** Наблюдение юзера: смена rate Г
BtnZoomIn/Def/Out всех панов). Урок: PanFromSender работает только для
контролов с Owner=панель (TLabel шапки — да, MakeFlatBtn-кнопки — нет).
**СТАТУС «грид-раскладка панов» (2026-07-12): РЕАЛИЗОВАНА, собирается, НА
ЭКРАНЕ НЕ ПРОВЕРЕНА, НЕ закоммичена.**
- Панель: регион пана обобщён до прямоугольника — `StackLeft/StackWidth`
(0/0 = вся ширина), Layout смещает ВСЁ по X0 (шапка/спектр/линейка/
сплиттер/водопад/ряд зума); `PositionPanZoomBar` получил X0 и 5-ю кнопку;
новая кнопка `FBtnGrid` («▦»/«▤», глифом рулит хозяин) + `GridClick`
(задать до Build) + `GridBtnEnabled`; ReparentTo переносит кнопку.
- MainForm: `FPanGridMode` (сессия), `FPanGridRowShare` (доля верхнего ряда,
0.15..0.85, дефолт 0.5), `FPanColShare[1..]` (доли колонок, init 1.0,
нормируются суммой), `FPanVSplitters[1..]` (вертикальный сплиттер СЛЕВА от
колонки пана i, crHSplit, создаётся в CreatePanadapter, free в
ClosePanadapter). `PanGridActive` = режим включён И >=2 доп. панов в стеке
(иначе автоткат в стек, режим помнится). LayoutPanStack: ветка грида — пан 0
верхний ряд во всю ширину (wideband внутри как в стеке), паны N колонками;
горизонтальный сплиттер ряда = сплиттер ПЕРВОЙ колонки во всю ширину
(PanSplitMouseDown/Up ветвятся по PanGridActive: в гриде правят
FPanGridRowShare напрямую), сплиттеры остальных колонок скрыты; вертикальные
PanVSplitMouse* — зеркало горизонтальных (призрак, min 15% ширины,
DShare=DeltaX/TotalW*ShareSum). Кнопка «▦/▤» видна при FPanGridMode или
>=3 застекованных панах (выключить можно всегда). PopOutPan обнуляет
StackLeft/Width и прячет V-сплиттер. Темизация: V-сплиттеры T.Border,
BtnGrid через StyleButton.
- Флаги/мышь/зум панов грид не трогает: всё в координатах канвы спектра,
канва целиком переезжает в регион-колонку.
- Проверить на экране: тумблер при 3 панах, оба типа сплиттеров, wideband в
гриде, pop-out/возврат из грида, закрытие пана в гриде (автоткат),
узкие колонки (зум/клик-тюн/drag), отсутствие регрессий при 1-2 панах.
**ФИКСЫ ПО ПЕРВОМУ ЭКРАННОМУ ТЕСТУ ГРИДА (2026-07-12, собирается, не
проверено):** три независимых бага из фидбека юзера.
1. **Наезд панов при выходе из грида (и вообще при 4 панах в стеке).**
LayoutPanStack делил высоту по долям (после add/close все доли равные,
при 4 панах = 25%), а Layout панели клампит спектр/водопад к минимумам
(MIN_SH=60/MIN_WH=40) — виджеты вылезали за регион, следующий пан
рисовался поверх (пан 0 терял водопад и ряд кнопок). Фикс:
`TPanafallPanel.MinLayoutHeight` (те же константы/DPI, что Layout) +
`PanMinHeight(PanId)` в MainForm (пан 0 += wideband `FPanWideH`);
раздача в стеке клампит каждый пан минимумом и режет раздутые так,
чтобы оставшимся хватило на их минимумы; в гриде Row0H клампится
минимумом пана 0 и минимумом нижнего ряда (макс. по колонкам);
драг межпанного сплиттера ограждён `Max(15%, минимум содержимого)`
в обеих ветках (стек/грид).
2. **«Блуждающие» кнопки после STOP (− − ⌂ +, кнопки на линейке, ⊞ накрыт).**
MakeFlatBtn создаёт кнопки с Owner=КОНТЕЙНЕР (не панель) → при гибели
пана (STOP → DestroyAllExtraPans → P.Free) кнопки /⌂/+/⊞/▦ НЕ
освобождались и оставались жить на PanelRight в старых координатах,
а PanOfZoomButton, не найдя пан, роутил их клики на главный зум.
Фикс: TPanafallPanel.Destroy явно освобождает FBtnZoomOut/Def/In,
FBtnAddPan, FBtnGrid (FBtnPopPan/ClosePan — Owner=FHeaderPanel,
умирают с ним). Перезапуск программы «лечил», потому что утечка —
в пределах процесса.
3. **Жор CPU (+~40% за пан).** SyncPanViews (тик, частота кадров) звал
SyncPanZoomUI с БЕЗУСЛОВНЫМ `PbPanZoom.Invalidate` на каждый пан каждый
кадр (регрессия cb6bdfa) = полный софт-рендер зум-бара + Qt-рекомпозит
@~50fps × N панов. Фикс: инвалидация только внутри
ZoomBar.SetFreq/SetState (они no-op при тех же значениях), событийный
Invalidate перенесён в RefreshPanZoom. Дополнительно жор усиливался
багом 1 (наезжающие GL-виджеты сверх окна). Замер юзера — после фикса.
Ответ на вопрос «почему только 3 доп. пана»: MAX_PANS=4 (WDSPEngine) —
пан 0 + 3 доп.; 6 было у СЛАЙСОВ (MAX_SLICES=6 доп.). Поднять можно (P2
позволяет много DDC), но сначала подтвердить CPU после фиксов.
Фиксы 1-3 ПОДТВЕРЖДЕНЫ юзером на экране 2026-07-12 («работает», CPU со
всеми панами 17-20%). Добит хвост:
4. **Пропорция спектр/водопад пана 0 не восстанавливалась после закрытия
панов (50/50 → 70/30).** Layout клампил ratio минимумами С ЗАПИСЬЮ в
FSplitterRatio: в маленьком регионе (стек панов) MIN_SH/AvailH ≈ 0.7
запоминался навсегда. Фикс: кламп в локальную EffRatio, FSplitterRatio
меняет только drag сплиттера юзером.
### 3.6 — Pluto+ (2r2t): второй пан на втором антенном входе
Опционально, после 3.0-3.3. Обычного Pluto НЕ касается (там один RX разведён).