mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 17:27:32 +00:00
feat(overlay): scrollable audio device list in AUD fly-out
Список устройств вывода ограничен AUD_MAX_VIS=6 видимыми строками — панель больше не растёт бесконечно и не уезжает за низ спектра. При большем числе устройств справа появляется полоса прокрутки ▲/▼ (строки сужаются под колонку стрелок), клик листает FAudScroll не закрывая панель; стрелки гаснут на краях. ≤6 устройств — как раньше, без стрелок. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+68
-7
@@ -58,6 +58,7 @@ type
|
||||
FCurDev: string; // имя текущего устройства ('' = default)
|
||||
|
||||
FPanel: TFlyPanel; // открытая fly-out панель
|
||||
FAudScroll: Integer; // прокрутка списка аудио-устройств (верхний индекс)
|
||||
FVolTrack: TRect; // трек громкости (локальные координаты)
|
||||
FVolDrag: Boolean;
|
||||
|
||||
@@ -159,6 +160,8 @@ const
|
||||
HIT_VOL = -24;
|
||||
HIT_SPLIT = -25;
|
||||
HIT_TX = -26;
|
||||
HIT_AUD_UP = -27;
|
||||
HIT_AUD_DN = -28;
|
||||
HIT_AGC_PICK_BASE = 100000;
|
||||
HIT_DEV_BASE = 200000;
|
||||
|
||||
@@ -173,6 +176,8 @@ const
|
||||
BAR_H = 24;
|
||||
ROW_H = 20;
|
||||
IGAP = 2;
|
||||
AUD_ROW_H = 17; // высота строки устройства в AUD-панели
|
||||
AUD_MAX_VIS = 6; // максимум видимых устройств (дальше — прокрутка)
|
||||
OVL_BASE_H = PAD + HDR_H + MET_H + FRQ_H + BAR_H + PAD; // = 96
|
||||
|
||||
// Палитра
|
||||
@@ -334,6 +339,7 @@ begin
|
||||
FVolume := 70; FMuted := False; FSplit := False; FTx := False;
|
||||
FTxSel := True; FSlice := 'A';
|
||||
FPanel := fpNone;
|
||||
FAudScroll := 0;
|
||||
FVolDrag := False;
|
||||
FDevNames := TStringList.Create;
|
||||
FCurDev := '';
|
||||
@@ -387,7 +393,7 @@ begin
|
||||
case FPanel of
|
||||
fpMode: Result := ROW_H*2 + IGAP + ROW_H + IGAP; // 2 ряда режимов + ряд фильтров
|
||||
fpDsp: Result := ROW_H + IGAP + ROW_H; // toggles + AGC
|
||||
fpAud: Result := Max(1, FDevNames.Count) * 17;
|
||||
fpAud: Result := Min(Max(1, FDevNames.Count), AUD_MAX_VIS) * AUD_ROW_H;
|
||||
else Result := 0;
|
||||
end;
|
||||
end;
|
||||
@@ -401,6 +407,7 @@ end;
|
||||
procedure TVfoOverlay.SetPanel(P: TFlyPanel);
|
||||
begin
|
||||
if FPanel = P then FPanel := fpNone else FPanel := P;
|
||||
if FPanel = fpAud then FAudScroll := 0; // список с начала
|
||||
Height := ComputeHeight;
|
||||
RequestInvalidate;
|
||||
end;
|
||||
@@ -681,11 +688,14 @@ begin
|
||||
end;
|
||||
|
||||
procedure TVfoOverlay.DrawAudPanel(C: TCanvas; X, Y, RowW: Integer);
|
||||
const
|
||||
ARROW_W = 15;
|
||||
var
|
||||
I: Integer;
|
||||
I, Slot, VisN, RowWidth, MaxScroll, PanelH, ArrowX, MidY, CY: Integer;
|
||||
HR: TRect;
|
||||
Nm: string;
|
||||
Cur: Boolean;
|
||||
Cur, Scrollable, CanUp, CanDn: Boolean;
|
||||
Tri: array[0..2] of TPoint;
|
||||
begin
|
||||
C.Font.Name := 'Courier New';
|
||||
C.Font.Size := 7;
|
||||
@@ -697,9 +707,18 @@ begin
|
||||
C.TextOut(X, Y + 2, '(нет устройств)');
|
||||
Exit;
|
||||
end;
|
||||
for I := 0 to FDevNames.Count - 1 do
|
||||
|
||||
VisN := Min(FDevNames.Count, AUD_MAX_VIS);
|
||||
Scrollable := FDevNames.Count > AUD_MAX_VIS;
|
||||
MaxScroll := FDevNames.Count - VisN;
|
||||
if FAudScroll > MaxScroll then FAudScroll := MaxScroll;
|
||||
if FAudScroll < 0 then FAudScroll := 0;
|
||||
if Scrollable then RowWidth := RowW - ARROW_W - 2 else RowWidth := RowW;
|
||||
|
||||
for Slot := 0 to VisN - 1 do
|
||||
begin
|
||||
HR := Rect(X, Y + I*17, X + RowW, Y + I*17 + 16);
|
||||
I := FAudScroll + Slot;
|
||||
HR := Rect(X, Y + Slot*AUD_ROW_H, X + RowWidth, Y + Slot*AUD_ROW_H + 16);
|
||||
Nm := FDevNames[I];
|
||||
Cur := (Nm = FCurDev) or ((FCurDev = '') and (I = 0));
|
||||
if Cur then C.Brush.Color := CLR_ACCENT_D
|
||||
@@ -712,13 +731,50 @@ begin
|
||||
C.RoundRect(HR.Left, HR.Top, HR.Right, HR.Bottom, 4, 4);
|
||||
if Cur then C.Font.Color := CLR_ACCENT else C.Font.Color := CLR_TEXT;
|
||||
C.Brush.Style := bsClear;
|
||||
if C.TextWidth(Nm) > RowW - 8 then
|
||||
while (Length(Nm) > 1) and (C.TextWidth(Nm + '…') > RowW - 8) do
|
||||
if C.TextWidth(Nm) > RowWidth - 8 then
|
||||
while (Length(Nm) > 1) and (C.TextWidth(Nm + '…') > RowWidth - 8) do
|
||||
SetLength(Nm, Length(Nm) - 1);
|
||||
if Nm <> FDevNames[I] then Nm := Nm + '…';
|
||||
C.TextOut(HR.Left + 4, HR.Top + (16 - C.TextHeight('A')) div 2, Nm);
|
||||
RegisterHit(HR, HIT_DEV_BASE + I);
|
||||
end;
|
||||
|
||||
if not Scrollable then Exit;
|
||||
|
||||
// Полоса прокрутки справа: ▲ (верх) / ▼ (низ) + счётчик позиции.
|
||||
PanelH := VisN * AUD_ROW_H - 1;
|
||||
ArrowX := X + RowWidth + 2;
|
||||
MidY := Y + PanelH div 2;
|
||||
CanUp := FAudScroll > 0;
|
||||
CanDn := FAudScroll < MaxScroll;
|
||||
|
||||
// верхняя стрелка
|
||||
HR := Rect(ArrowX, Y, X + RowW, MidY - 1);
|
||||
C.Brush.Color := CLR_BTN_NORM; C.Brush.Style := bsSolid;
|
||||
C.Pen.Color := CLR_BTN_NORM; C.Pen.Style := psSolid;
|
||||
C.RoundRect(HR.Left, HR.Top, HR.Right, HR.Bottom, 4, 4);
|
||||
CY := (HR.Top + HR.Bottom) div 2;
|
||||
if CanUp then C.Brush.Color := CLR_TEXT else C.Brush.Color := CLR_DIM;
|
||||
C.Pen.Color := C.Brush.Color;
|
||||
Tri[0] := Point((HR.Left+HR.Right) div 2, CY - 3);
|
||||
Tri[1] := Point((HR.Left+HR.Right) div 2 - 4, CY + 2);
|
||||
Tri[2] := Point((HR.Left+HR.Right) div 2 + 4, CY + 2);
|
||||
C.Polygon(Tri);
|
||||
RegisterHit(HR, HIT_AUD_UP);
|
||||
|
||||
// нижняя стрелка
|
||||
HR := Rect(ArrowX, MidY + 1, X + RowW, Y + PanelH);
|
||||
C.Brush.Color := CLR_BTN_NORM; C.Brush.Style := bsSolid;
|
||||
C.Pen.Color := CLR_BTN_NORM; C.Pen.Style := psSolid;
|
||||
C.RoundRect(HR.Left, HR.Top, HR.Right, HR.Bottom, 4, 4);
|
||||
CY := (HR.Top + HR.Bottom) div 2;
|
||||
if CanDn then C.Brush.Color := CLR_TEXT else C.Brush.Color := CLR_DIM;
|
||||
C.Pen.Color := C.Brush.Color;
|
||||
Tri[0] := Point((HR.Left+HR.Right) div 2, CY + 3);
|
||||
Tri[1] := Point((HR.Left+HR.Right) div 2 - 4, CY - 2);
|
||||
Tri[2] := Point((HR.Left+HR.Right) div 2 + 4, CY - 2);
|
||||
C.Polygon(Tri);
|
||||
RegisterHit(HR, HIT_AUD_DN);
|
||||
end;
|
||||
|
||||
{ ---- Основная отрисовка ---- }
|
||||
@@ -893,6 +949,11 @@ begin
|
||||
if Assigned(FOnMute) then FOnMute(Self); Exit; end;
|
||||
HIT_SPLIT: begin if Assigned(FOnSplit) then FOnSplit(Self); Exit; end;
|
||||
HIT_TX: begin if Assigned(FOnTxSelect) then FOnTxSelect(Self); Exit; end;
|
||||
HIT_AUD_UP: begin if FAudScroll > 0 then Dec(FAudScroll);
|
||||
RequestInvalidate; Exit; end;
|
||||
HIT_AUD_DN: begin if FAudScroll < FDevNames.Count - AUD_MAX_VIS then
|
||||
Inc(FAudScroll);
|
||||
RequestInvalidate; Exit; end;
|
||||
end;
|
||||
|
||||
// Устройство аудио
|
||||
|
||||
Reference in New Issue
Block a user