mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 20:37:33 +00:00
ui(vfo): колесо мыши прокручивает список устройств в AUD
VfoOverlay запоминает прямоугольник списка (FAudListRect) и обрабатывает колесо над ним (HandleMouseWheel): шаг = одна строка. Если курсор в этой зоне, событие считается обработанным и не уходит в спектр — частота не съезжает даже когда список целиком помещается и крутить нечего. PanafallPanel.DispatchFlagsMouseWheel перебирает главный флаг и флаги слайсов (как остальные Dispatch*), MainForm.FormMouseWheel зовёт его по всем панам первым делом после дисплеев VFO; координаты берутся через PbSpectrum.ScreenToClient(Mouse.CursorPos), поэтому работает и в pop-out. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -7885,12 +7885,27 @@ var
|
|||||||
SLo, SHi, SNew: Double;
|
SLo, SHi, SNew: Double;
|
||||||
Sl: TCtrlSlice;
|
Sl: TCtrlSlice;
|
||||||
SlicePan: TPanafallPanel;
|
SlicePan: TPanafallPanel;
|
||||||
|
P: TPoint;
|
||||||
begin
|
begin
|
||||||
// Над дисплеем VFO (A или B) колесо обрабатывает сам TFreqDisplay поразрядно
|
// Над дисплеем VFO (A или B) колесо обрабатывает сам TFreqDisplay поразрядно
|
||||||
// (включая неактивный VFO). Не дублируем здесь, иначе менялись бы обе частоты:
|
// (включая неактивный VFO). Не дублируем здесь, иначе менялись бы обе частоты:
|
||||||
// виджет крутил бы B, а этот хендлер — активный A.
|
// виджет крутил бы B, а этот хендлер — активный A.
|
||||||
if OverFreqDisp(FreqDispA) or OverFreqDisp(FreqDispB) then Exit;
|
if OverFreqDisp(FreqDispA) or OverFreqDisp(FreqDispB) then Exit;
|
||||||
|
|
||||||
|
// Колесо над раскрытым списком устройств во флаге — прокрутка этого списка.
|
||||||
|
for i := 0 to MAX_PANS - 1 do
|
||||||
|
if (FPans[i] <> nil) and Assigned(FPans[i].PbSpectrum) and
|
||||||
|
FPans[i].PbSpectrum.Visible then
|
||||||
|
begin
|
||||||
|
P := FPans[i].PbSpectrum.ScreenToClient(Mouse.CursorPos);
|
||||||
|
if FPans[i].DispatchFlagsMouseWheel(P.X, P.Y, WheelDelta) then
|
||||||
|
begin
|
||||||
|
MarkPanDirty(FPans[i]);
|
||||||
|
Handled := True;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
// Колесо над маркером слайса (любого пана) — двигаем частоту ЭТОГО слайса.
|
// Колесо над маркером слайса (любого пана) — двигаем частоту ЭТОГО слайса.
|
||||||
SliceId := 0;
|
SliceId := 0;
|
||||||
SlicePan := nil;
|
SlicePan := nil;
|
||||||
|
|||||||
@@ -292,6 +292,7 @@ type
|
|||||||
procedure DispatchFlagsMouseMove(X, Y: Integer);
|
procedure DispatchFlagsMouseMove(X, Y: Integer);
|
||||||
function DispatchFlagsMouseUp(X, Y: Integer): Boolean;
|
function DispatchFlagsMouseUp(X, Y: Integer): Boolean;
|
||||||
procedure DispatchFlagsMouseLeave;
|
procedure DispatchFlagsMouseLeave;
|
||||||
|
function DispatchFlagsMouseWheel(X, Y, WheelDelta: Integer): Boolean;
|
||||||
|
|
||||||
property Controller: TRadioController read FController write FController;
|
property Controller: TRadioController read FController write FController;
|
||||||
property MainFlag: TVfoOverlay read FMainFlag;
|
property MainFlag: TVfoOverlay read FMainFlag;
|
||||||
@@ -1557,4 +1558,24 @@ begin
|
|||||||
if FSliceFlags[i] <> nil then FSliceFlags[i].HandleMouseLeave;
|
if FSliceFlags[i] <> nil then FSliceFlags[i].HandleMouseLeave;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
// Колесо над раскрытым списком устройств во флаге: прокрутка списка вместо
|
||||||
|
// перестройки частоты. Координаты — в системе спектра (как у остальных Handle*).
|
||||||
|
function TPanafallPanel.DispatchFlagsMouseWheel(X, Y, WheelDelta: Integer): Boolean;
|
||||||
|
var i: Integer;
|
||||||
|
begin
|
||||||
|
Result := False;
|
||||||
|
if Assigned(FMainFlag) and FMainFlag.Visible then
|
||||||
|
begin
|
||||||
|
FActiveFlag := FMainFlag;
|
||||||
|
if FMainFlag.HandleMouseWheel(X, Y, WheelDelta) then Exit(True);
|
||||||
|
end;
|
||||||
|
for i := 0 to High(FSliceFlags) do
|
||||||
|
if (FSliceFlags[i] <> nil) and FSliceFlags[i].Visible then
|
||||||
|
begin
|
||||||
|
FActiveFlag := FSliceFlags[i];
|
||||||
|
if FSliceFlags[i].HandleMouseWheel(X, Y, WheelDelta) then Exit(True);
|
||||||
|
end;
|
||||||
|
FActiveFlag := nil;
|
||||||
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|||||||
@@ -101,6 +101,7 @@ type
|
|||||||
|
|
||||||
FPanel: TFlyPanel; // открытая fly-out панель
|
FPanel: TFlyPanel; // открытая fly-out панель
|
||||||
FAudScroll: Integer; // прокрутка списка аудио-устройств (верхний индекс)
|
FAudScroll: Integer; // прокрутка списка аудио-устройств (верхний индекс)
|
||||||
|
FAudListRect: TRect; // область списка AUD (лок. коорд.) — зона колёсика
|
||||||
FVolTrack: TRect; // трек громкости (локальные координаты)
|
FVolTrack: TRect; // трек громкости (локальные координаты)
|
||||||
FVolDrag: Boolean;
|
FVolDrag: Boolean;
|
||||||
FSqlTrack: TRect; // трек squelch в DSP-панели (лок. координаты)
|
FSqlTrack: TRect; // трек squelch в DSP-панели (лок. координаты)
|
||||||
@@ -196,6 +197,8 @@ type
|
|||||||
function HandleMouseMove(X, Y: Integer): Boolean;
|
function HandleMouseMove(X, Y: Integer): Boolean;
|
||||||
function HandleMouseUp(X, Y: Integer): Boolean;
|
function HandleMouseUp(X, Y: Integer): Boolean;
|
||||||
function HandleMouseLeave: Boolean;
|
function HandleMouseLeave: Boolean;
|
||||||
|
// Колесо над списком устройств AUD (координаты — как у HandleMouseDown).
|
||||||
|
function HandleMouseWheel(X, Y, WheelDelta: Integer): Boolean;
|
||||||
procedure SetState(AMode, ABW: Integer; AVfoHz, ASMeterDB: Double);
|
procedure SetState(AMode, ABW: Integer; AVfoHz, ASMeterDB: Double);
|
||||||
procedure SetDSPState(ANRMode, ANBMode: Integer; ASNBOn, AANFOn: Boolean;
|
procedure SetDSPState(ANRMode, ANBMode: Integer; ASNBOn, AANFOn: Boolean;
|
||||||
AAGCMode: Integer);
|
AAGCMode: Integer);
|
||||||
@@ -1015,6 +1018,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
VisN := Min(Cnt, AUD_MAX_VIS);
|
VisN := Min(Cnt, AUD_MAX_VIS);
|
||||||
|
FAudListRect := Rect(X, Y, X + RowW, Y + VisN*AUD_ROW_H); // зона колёсика
|
||||||
Scrollable := Cnt > AUD_MAX_VIS;
|
Scrollable := Cnt > AUD_MAX_VIS;
|
||||||
MaxScroll := Cnt - VisN;
|
MaxScroll := Cnt - VisN;
|
||||||
if FAudScroll > MaxScroll then FAudScroll := MaxScroll;
|
if FAudScroll > MaxScroll then FAudScroll := MaxScroll;
|
||||||
@@ -1093,6 +1097,7 @@ var
|
|||||||
BarL, BarW, MeterX: Integer;
|
BarL, BarW, MeterX: Integer;
|
||||||
begin
|
begin
|
||||||
FHitCount := 0;
|
FHitCount := 0;
|
||||||
|
FAudListRect := Rect(0, 0, 0, 0); // выставит DrawAudPanel, если панель открыта
|
||||||
|
|
||||||
// Фон карточки
|
// Фон карточки
|
||||||
C.Brush.Color := CLR_CARD_BG;
|
C.Brush.Color := CLR_CARD_BG;
|
||||||
@@ -1506,6 +1511,22 @@ begin
|
|||||||
Result := True; // клик был по накладке — не пускаем его в спектр
|
Result := True; // клик был по накладке — не пускаем его в спектр
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TVfoOverlay.HandleMouseWheel(X, Y, WheelDelta: Integer): Boolean;
|
||||||
|
var
|
||||||
|
MaxScroll, Old: Integer;
|
||||||
|
begin
|
||||||
|
Result := False;
|
||||||
|
if (not Visible) or (FPanel <> fpAud) then Exit;
|
||||||
|
if not PtInRect(FAudListRect, Point(X - Left, Y - Top)) then Exit;
|
||||||
|
Result := True; // зона наша — колесо в спектр не пускаем
|
||||||
|
MaxScroll := AudRowCount - AUD_MAX_VIS;
|
||||||
|
if MaxScroll <= 0 then Exit; // список целиком виден — крутить нечего
|
||||||
|
Old := FAudScroll;
|
||||||
|
if WheelDelta > 0 then Dec(FAudScroll) else Inc(FAudScroll);
|
||||||
|
FAudScroll := EnsureRange(FAudScroll, 0, MaxScroll);
|
||||||
|
if FAudScroll <> Old then RequestInvalidate;
|
||||||
|
end;
|
||||||
|
|
||||||
function TVfoOverlay.HandleMouseLeave: Boolean;
|
function TVfoOverlay.HandleMouseLeave: Boolean;
|
||||||
begin
|
begin
|
||||||
Result := False;
|
Result := False;
|
||||||
|
|||||||
Reference in New Issue
Block a user