fix(ui): DPI-масштабирование SettingsForm/DeviceForm + общий DpiScale

Вся раскладка окон, построенных кодом (SettingsForm, DeviceForm), была
захардкожена в пикселях под неявные 96 DPI — на Windows 125-200% или
HiDPI-десктопах контролы физически не росли вместе с укрупнившимся
шрифтом. Добавлено масштабирование SetBounds через MulDiv(V,
Screen.PixelsPerInch, 96) на каждой листовой точке потребления
(const-блоки раскладки не трогались).

Общий DpiScale вынесен в новый юнит DpiUtils.pas — убрана дублированная
копия одноимённого приватного метода в 9 классах (FlatCheckBox,
FlatComboBox, FlatListBox, FlatSpinEdit, FlatFloatSpinEdit, FlatEdit,
FlatRadioButton, FlatPopupMenu, SettingsForm, DeviceForm) и инлайн-MulDiv
без обёртки в MainForm.pas/PanafallPanel.pas.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-29 16:05:39 +03:00
co-authored by Claude Sonnet 5
parent 041bc6ba7a
commit c95620fb23
14 changed files with 222 additions and 237 deletions
+9 -9
View File
@@ -35,7 +35,7 @@ uses
LCLIntf, LCLType,
OpenGLContextEx,
AppTheme, WDSPEngine, RadioController, DMRDecoder, VfoOverlay,
SpectrumView, SpectrumViewOpengl, PanZoomBar, FlatButton;
SpectrumView, SpectrumViewOpengl, PanZoomBar, FlatButton, DpiUtils;
type
TWireFlagEvent = procedure(O: TVfoOverlay) of object;
@@ -682,7 +682,7 @@ begin
if FBtnAddPan <> nil then FBtnAddPan.Visible := AVisible and WantAdd;
if FBtnGrid <> nil then FBtnGrid.Visible := AVisible and WantGrid;
if not AVisible then Exit;
Gap := MulDiv(2, Screen.PixelsPerInch, 96);
Gap := DpiScale(2);
BtnW := H; // квадратные кнопки в высоту строки
NBtns := 3;
if WantAdd then Inc(NBtns);
@@ -716,9 +716,9 @@ const
var
RULER_H, PANZOOM_H, HEADER_H: Integer;
begin
RULER_H := MulDiv(18, Screen.PixelsPerInch, 96);
PANZOOM_H := MulDiv(22, Screen.PixelsPerInch, 96);
HEADER_H := MulDiv(20, Screen.PixelsPerInch, 96);
RULER_H := DpiScale(18);
PANZOOM_H := DpiScale(22);
HEADER_H := DpiScale(20);
Result := ATopOffset;
if FHeaderVisible then Inc(Result, HEADER_H);
if (AShowSpectrum or AShowWaterfall) and FShowZoomRow then
@@ -751,7 +751,7 @@ begin
FShowSpectrum := AShowSpectrum;
FShowWaterfall := AShowWaterfall;
FSplitAvailH := 0; // валидно только в режиме «спектр+водопад» (ниже)
RULER_H := MulDiv(18, Screen.PixelsPerInch, 96);
RULER_H := DpiScale(18);
// Регион пана — прямоугольник [X0..X0+RW) × [FStackTop..RH): грид-раскладка
// ставит паны колонками; 0/0 по каждой оси = весь родитель.
X0 := FStackLeft;
@@ -767,7 +767,7 @@ begin
else
RH := FParent.ClientHeight;
// Шапка пана — первой строкой региона (видна при панах >= 2).
HEADER_H := MulDiv(20, Screen.PixelsPerInch, 96);
HEADER_H := DpiScale(20);
if FHeaderPanel <> nil then
begin
FHeaderPanel.Visible := FHeaderVisible;
@@ -778,7 +778,7 @@ begin
end;
end;
// Резервируем низ под панель пана/зума (видна, если виден спектр или водопад).
PANZOOM_H := MulDiv(22, Screen.PixelsPerInch, 96);
PANZOOM_H := DpiScale(22);
ShowPZ := (AShowSpectrum or AShowWaterfall) and FShowZoomRow;
PositionPanZoomBar(X0, RH - PANZOOM_H, RW, PANZOOM_H, ShowPZ);
if ShowPZ then RH := RH - PANZOOM_H;
@@ -943,7 +943,7 @@ const
MIN_SH = 60;
MIN_WH = 40;
begin
RULER_H := MulDiv(18, Screen.PixelsPerInch, 96);
RULER_H := DpiScale(18);
if not FSplitterDrag then Exit;
// Геометрия региона ЭТОГО пана из последнего Layout (стек панов!),
// а не от всего родителя.