mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 18:43:51 +00:00
ui(spectrum): полоса главного фильтра — как у слайсов, со своим оттенком
Главный фильтр рисовался иначе, чем слайсовые полосы, причём в CPU-пути сильнее, чем в GL. 1. Порядок отрисовки. Кромки, несущая и её треугольник у главного шли ПОСЛЕ кривой спектра, у слайсов — до неё, а в GL-вьюхе весь блок фильтров идёт перед DrawSpectrumCurve. Из-за этого на CPU главная полоса единственная лезла поверх сигнала и выглядела жирнее и ярче слайсовых при тех же цвете и толщине линий. Блок перенесён к слайсам, до кривой: порядок кадра теперь одинаков у обоих путей. 2. Заливка. Была НЕПРОЗРАЧНОЙ, рядом с просвечивающими слайсовыми смотрелась плотным блоком. Теперь та же полупрозрачность, что у слайсов; прозрачность вынесена в общие SPEC_BAND_ALPHA/SPEC_BAND_ALPHA_TX (VfoOverlay, рядом с палитрой слайсов) — раньше это были четыре магических числа по двум вьюхам. Осиротевшая FillBandRaw удалена. 3. Цвет. С полупрозрачностью полоса перестала читаться: SpecFilter (34,78,106) почти совпадает с нижним цветом фонового градиента спектра (31,79,108), и заливка давала не оттенок, а затемнение — над низом градиента выходило ровно (32,79,108), то есть фон. Полосе дан свой цвет темы SpecFilterBand: тёплый янтарь RGB(255,150,40) на тёмной (фон сине-стальной, тёплое на нём читается) и насыщённый зелёный RGB(60,150,60) на светлой. SpecFilter остался подложкой подписей AGC — иначе перекрасились бы и они. 4. Слайс B перекрашен из оранжевого в васильковый RGB(97,118,255): с янтарной полосой главного фильтра оранжевый стал неразличим. Оттенок выбран по свободному месту в круге: заняты 0°(TX), 31°(полоса), 55°(E), 132°(A), 190°(C), 195°(G), 276°(F), 308°(D); самый широкий промежуток 195..276°, середина ≈236°. Палитра одна на всё, поэтому вместе с полосой и несущей перекрашиваются буква слайса на спектре и бейдж во флаге VfoOverlay. Сборка ewsdr (--ws=qt6) и ewsdrd — ОК. На экране не проверено: нужен эфир со слайсами; цвета правятся одной строкой (SpecFilterBand в AppTheme, SLICE_COLORS в VfoOverlay). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+31
-57
@@ -185,7 +185,6 @@ type
|
||||
procedure DrawIMDMarkersRaw(W, H: Integer; DBmax, InvRange: Double);
|
||||
procedure RawCircle(CX, CY, R: Integer; Color: TColor);
|
||||
procedure BlendBand(X1, X2, H: Integer; R, G, B, Alpha: Byte);
|
||||
procedure FillBandRaw(X1, X2, H: Integer; Color: TColor);
|
||||
procedure CopyGridToSpectrum(W, H: Integer);
|
||||
procedure DrawADCOverloadRaw(W, H: Integer);
|
||||
procedure CalcFilterBandX(VfoFreq: Double; W: Integer;
|
||||
@@ -1168,41 +1167,6 @@ end;
|
||||
// Canvas.FillRect для полосы фильтра в DrawSpectrum: полоса рисуется в
|
||||
// raw-фазе (между memcpy сетки и градиентом), а FillRect дёргал бы Canvas
|
||||
// и форсил лишнюю синхронизацию битмапа на Qt6.
|
||||
procedure TSpectrumView.FillBandRaw(X1, X2, H: Integer; Color: TColor);
|
||||
var
|
||||
Y, W: Integer;
|
||||
Row: PLongWord;
|
||||
Px: LongWord;
|
||||
R, G, B: Byte;
|
||||
begin
|
||||
if FSpectrumBitmap = nil then Exit;
|
||||
W := FSpectrumBitmap.Width;
|
||||
if X1 < 0 then X1 := 0;
|
||||
if X2 > W then X2 := W;
|
||||
if X2 <= X1 then Exit;
|
||||
R := Color and $FF; G := (Color shr 8) and $FF; B := (Color shr 16) and $FF;
|
||||
{$IFDEF DARWIN}
|
||||
// ARGB в памяти (см. BlendBand): байт 0 = альфа, дальше R,G,B.
|
||||
Px := LongWord($FF) or (LongWord(R) shl 8) or (LongWord(G) shl 16) or
|
||||
(LongWord(B) shl 24);
|
||||
{$ELSE}
|
||||
// BGRA в памяти: байты B,G,R,A.
|
||||
Px := LongWord(B) or (LongWord(G) shl 8) or (LongWord(R) shl 16) or $FF000000;
|
||||
{$ENDIF}
|
||||
FSpectrumBitmap.BeginUpdate(False);
|
||||
try
|
||||
for Y := 0 to H - 1 do
|
||||
begin
|
||||
Row := PLongWord(FSpectrumBitmap.ScanLine[Y]);
|
||||
if Row = nil then Continue;
|
||||
Inc(Row, X1);
|
||||
FillDWord(Row^, X2 - X1, Px);
|
||||
end;
|
||||
finally
|
||||
FSpectrumBitmap.EndUpdate(False);
|
||||
end;
|
||||
end;
|
||||
|
||||
// Маркер фильтра каждого слайса (B+) на спектре — полупрозрачная полоса
|
||||
// пропускания + края + центральная несущая. Янтарный цвет, как в GL-вьюхе
|
||||
// (SpectrumViewOpengl.DrawSliceFilterMarkers). Полосы (raw ScanLine-блендинг)
|
||||
@@ -1224,7 +1188,7 @@ begin
|
||||
CalcSliceBandX(O, W, SX1, SX2, SVfoX);
|
||||
if SX2 > SX1 then
|
||||
BlendBand(SX1, SX2, H, Clr and $FF, (Clr shr 8) and $FF, (Clr shr 16) and $FF,
|
||||
IfThen(O.TxActive, 100, 60));
|
||||
IfThen(O.TxActive, SPEC_BAND_ALPHA_TX, SPEC_BAND_ALPHA));
|
||||
end;
|
||||
end;
|
||||
|
||||
@@ -1789,7 +1753,14 @@ begin
|
||||
end else
|
||||
if X2 > X1 then BlendBand(X1, X2, H, $E0, $30, $30, 100);
|
||||
end else
|
||||
if X2 > X1 then FillBandRaw(X1, X2, H, FTheme.SpecFilter);
|
||||
// Полупрозрачная заливка тем же способом, что у слайсов (SPEC_BAND_ALPHA):
|
||||
// раньше главная полоса заливалась НЕПРОЗРАЧНО и выглядела плотным блоком
|
||||
// рядом с просвечивающими слайсовыми. Цвет — SpecFilterBand (свой, не
|
||||
// подложка подписей AGC): см. комментарий в AppTheme.
|
||||
if X2 > X1 then
|
||||
BlendBand(X1, X2, H, FTheme.SpecFilterBand and $FF,
|
||||
(FTheme.SpecFilterBand shr 8) and $FF,
|
||||
(FTheme.SpecFilterBand shr 16) and $FF, SPEC_BAND_ALPHA);
|
||||
|
||||
// Полосы фильтра слайсов (B+) — под градиентом/кривой, как в GL-вьюхе.
|
||||
DrawSliceFilterBands(W, H);
|
||||
@@ -1800,16 +1771,34 @@ begin
|
||||
DrawSpectrumGradient(FSpPts, W, H);
|
||||
|
||||
|
||||
// ★ Кромки, несущая и буква ГЛАВНОГО фильтра — здесь, ДО кривой спектра,
|
||||
// ровно как у слайсов ниже и как в GL-вьюхе (там весь блок фильтров идёт
|
||||
// перед DrawSpectrumCurve). Раньше этот кусок стоял ПОСЛЕ кривой, и на
|
||||
// CPU-пути главный фильтр единственный лез поверх сигнала — с виду толще и
|
||||
// ярче слайсовых, хотя цвета и толщина те же.
|
||||
RawVLine(X1, 0, H - 1, FTheme.SpecFilterEdge);
|
||||
RawVLine(X2, 0, H - 1, FTheme.SpecFilterEdge);
|
||||
// Буква главного флага (A) на его полосе — только когда есть слайсы,
|
||||
// иначе одиночный приём не засоряем. Букву запоминаем: под неё ниже
|
||||
// иначе одиночный приём не засоряем. Букву запоминаем: под неё
|
||||
// подстраиваются вертикаль несущей и её треугольник.
|
||||
MainLetter := #0;
|
||||
if (FSliceOverlays <> nil) and (FSliceOverlays.Count > 0) and
|
||||
(FActiveVfo = 0) and Assigned(FVfoOverlay) then
|
||||
begin
|
||||
MainLetter := FVfoOverlay.SliceLetter;
|
||||
DrawBandLetterRaw(X1, X2, MainLetter, SliceColor(MainLetter));
|
||||
CarrY := CarrierTopY(X1, X2, VfoX, MainLetter);
|
||||
RawVLine(VfoX, CarrY, H - 13, FTheme.SpecVfoCursor, 2);
|
||||
RawTriangleDown(VfoX, CarrY, 5, 8, FTheme.SpecVfoCursor);
|
||||
if FTXOverlay and (FTXVfoIndex <> FActiveVfo) then
|
||||
begin
|
||||
RawVLine(TXX1, 0, H - 1, TColor($002030E0));
|
||||
RawVLine(TXX2, 0, H - 1, TColor($002030E0));
|
||||
// Буква нарисована на RX-полосе (X1..X2) — с ней и сверяемся.
|
||||
CarrY := CarrierTopY(X1, X2, TXVfoX, MainLetter);
|
||||
RawVLine(TXVfoX, CarrY, H - 13, TColor($002030E0), 2);
|
||||
RawTriangleDown(TXVfoX, CarrY, 5, 8, TColor($002030E0));
|
||||
end;
|
||||
if MainLetter <> #0 then
|
||||
DrawBandLetterRaw(X1, X2, MainLetter, SliceColor(MainLetter));
|
||||
|
||||
// Края/несущие/буквы слайсов (полосы уже нарисованы выше).
|
||||
DrawSliceFilterLinesRaw(W, H);
|
||||
@@ -1845,22 +1834,7 @@ begin
|
||||
// Линия спектра
|
||||
RawCurve(W, FTheme.SpecLine);
|
||||
|
||||
// Края фильтра + VFO
|
||||
RawVLine(X1, 0, H - 1, FTheme.SpecFilterEdge);
|
||||
RawVLine(X2, 0, H - 1, FTheme.SpecFilterEdge);
|
||||
// Несущая и её треугольник — под буквой полосы, если она там есть.
|
||||
CarrY := CarrierTopY(X1, X2, VfoX, MainLetter);
|
||||
RawVLine(VfoX, CarrY, H - 13, FTheme.SpecVfoCursor, 2);
|
||||
RawTriangleDown(VfoX, CarrY, 5, 8, FTheme.SpecVfoCursor);
|
||||
if FTXOverlay and (FTXVfoIndex <> FActiveVfo) then
|
||||
begin
|
||||
RawVLine(TXX1, 0, H - 1, TColor($002030E0));
|
||||
RawVLine(TXX2, 0, H - 1, TColor($002030E0));
|
||||
// Буква нарисована на RX-полосе (X1..X2) — с ней и сверяемся.
|
||||
CarrY := CarrierTopY(X1, X2, TXVfoX, MainLetter);
|
||||
RawVLine(TXVfoX, CarrY, H - 13, TColor($002030E0), 2);
|
||||
RawTriangleDown(TXVfoX, CarrY, 5, 8, TColor($002030E0));
|
||||
end;
|
||||
// (кромки/несущая главного фильтра нарисованы выше — до кривой)
|
||||
|
||||
if FMarkerActive then DrawMarkerLineRaw(W, H);
|
||||
if FBeaconMarkActive or FBeaconDecActive then DrawBeaconMarkersRaw(W, H);
|
||||
|
||||
Reference in New Issue
Block a user