diff --git a/MainForm.pas b/MainForm.pas index be3f9c7..0cf24af 100644 --- a/MainForm.pas +++ b/MainForm.pas @@ -90,6 +90,10 @@ const MODE_NAMES: array[0..MODE_COUNT-1] of string = ( 'LSB','USB','DSB','CWL','CWU','FM','AM','SAM'); + SMETER_WIDTH_RATIO = 0.32; + SMETER_MARGIN = 3; + TOP_SMETER_GAP = 72; + type TDeviceItem = record Dev: THPSDRDevice; @@ -275,7 +279,6 @@ type BtnVfoACopyB: TFlatButton; BtnVfoBCopyA: TFlatButton; PanelTopVfoB: TPanel; - PanelTopVfoSep: TPanel; PanelBands: TPanel; BtnBand: array[0..BAND_COUNT-1] of TFlatButton; @@ -1311,12 +1314,6 @@ begin PanelTopVfoB.BevelOuter := bvNone; PanelTopVfoB.Color := CLR_PANEL; - PanelTopVfoSep := TPanel.Create(Self); - PanelTopVfoSep.Parent := Self; - PanelTopVfoSep.SetBounds(0, 0, 1, 60); - PanelTopVfoSep.BevelOuter := bvNone; - PanelTopVfoSep.Color := CLR_TEXTDIM; - PanelVfoB := TPanel.Create(Self); PanelVfoB.Parent := PanelTopVfoB; PanelVfoB.SetBounds(0, 0, TOP_VFO_W, TOP_VFO_FREQ_H); @@ -1756,14 +1753,10 @@ procedure TMainForm.LayoutTopVfoBlock; const MARGIN = 4; TOP_OFFSET = 2; + TOP_VFO_MIN_W = 244; TOP_VFO_BTN_H = 14; TOP_VFO_FREQ_H = 47; SEP_GAP = 4; - SEP_W = 1; - SEP_TOP_OFFSET = 10; - SEP_BOTTOM_OFFSET = 8; - S_METER_GAP = SEP_GAP + SEP_W + SEP_GAP + 2; - SEP_SHIFT_LEFT = 3; SETTINGS_GAP = 4; BTN_GAP = 4; var @@ -1771,71 +1764,73 @@ var BtnY: Integer; BtnRowW: Integer; BtnX: Integer; - SepDrawLeft: Integer; SepLeft: Integer; LeftEdge: Integer; RightW: Integer; SMW: Integer; SMLeft: Integer; + TopVfoW: Integer; + NeedFreqW: Integer; + NeedBtnW: Integer; begin - if (PanelToolbar = nil) or (PanelTopVfoB = nil) or (PanelTopVfoSep = nil) then Exit; + if (PanelToolbar = nil) or (PanelTopVfoB = nil) then Exit; - SepLeft := PanelToolbar.ClientWidth - MARGIN - SEP_W; + Canvas.Font.Name := FreqDispB.FontName; + Canvas.Font.Size := FreqDispB.FontSize; + Canvas.Font.Style := [fsBold]; + NeedFreqW := FreqDispB.Left + Canvas.TextWidth('000.000.000') + 8; + NeedBtnW := BtnVfoSwap.Width + BtnVfoACopyB.Width + BtnVfoBCopyA.Width + + BTN_GAP * 2 + 8; + TopVfoW := Max(TOP_VFO_MIN_W, Max(NeedFreqW, NeedBtnW)); + + SepLeft := PanelToolbar.ClientWidth - MARGIN; if PanelLeft <> nil then begin RightW := ClientWidth - PanelLeft.Width; if RightW > 200 then begin - SMW := Round(RightW * 0.40); - SMLeft := ClientWidth - SMW - 3; - SepLeft := Min(SepLeft, SMLeft - SEP_GAP - SEP_W - 2); + SMW := Round(RightW * SMETER_WIDTH_RATIO); + SMLeft := ClientWidth - SMW - SMETER_MARGIN; + SepLeft := Min(SepLeft, SMLeft - TOP_SMETER_GAP); end; end; - LeftEdge := SepLeft - SEP_GAP - PanelTopVfoB.Width; + LeftEdge := SepLeft - SEP_GAP - TopVfoW; if BtnSettings <> nil then LeftEdge := Max(LeftEdge, BtnSettings.Left + BtnSettings.Width + SETTINGS_GAP); - if LeftEdge + PanelTopVfoB.Width > SepLeft - SEP_GAP then + if LeftEdge + TopVfoW > SepLeft - SEP_GAP then begin PanelTopVfoB.Visible := False; - PanelTopVfoSep.Visible := False; Exit; end; PanelTopVfoB.Visible := True; - PanelTopVfoSep.Visible := True; BlockH := PanelToolbar.Height + PanelSpanButtons.Height - (MARGIN * 2); if BlockH < 56 then BlockH := 56; - PanelTopVfoB.SetBounds(LeftEdge, TOP_OFFSET, PanelTopVfoB.Width, BlockH); - PanelVfoB.SetBounds(0, 0, PanelTopVfoB.Width, TOP_VFO_FREQ_H); + PanelTopVfoB.SetBounds(LeftEdge, TOP_OFFSET, TopVfoW, BlockH); + PanelVfoB.SetBounds(0, 0, TopVfoW, TOP_VFO_FREQ_H); + FreqDispB.SetBounds(FreqDispB.Left, FreqDispB.Top, + Max(20, TopVfoW - FreqDispB.Left), TOP_VFO_FREQ_H); BtnTopVfoBSelect.Left := FreqDispB.Left - BtnTopVfoBSelect.Width; BtnTopVfoBTX.Left := FreqDispB.Left - BtnTopVfoBTX.Width; BtnY := PanelTopVfoB.Height - TOP_VFO_BTN_H - 8; if BtnY < 42 then BtnY := 42; - PanelVfoButtons.SetBounds(4, BtnY, PanelTopVfoB.Width - 8, TOP_VFO_BTN_H); + PanelVfoButtons.SetBounds(4, BtnY, TopVfoW - 8, TOP_VFO_BTN_H); BtnRowW := BtnVfoSwap.Width + BtnVfoACopyB.Width + BtnVfoBCopyA.Width + BTN_GAP * 2; BtnX := FreqDispB.Left + (FreqDispB.Width - BtnRowW) div 2 - PanelVfoButtons.Left; if BtnX < 0 then BtnX := 0; BtnVfoSwap.Left := BtnX; BtnVfoACopyB.Left := BtnVfoSwap.Left + BtnVfoSwap.Width + BTN_GAP; BtnVfoBCopyA.Left := BtnVfoACopyB.Left + BtnVfoACopyB.Width + BTN_GAP; - SepDrawLeft := SepLeft - SEP_SHIFT_LEFT; - PanelTopVfoSep.SetBounds(SepDrawLeft, - TOP_OFFSET + SEP_TOP_OFFSET, SEP_W, - PanelTopVfoB.Height - SEP_TOP_OFFSET - SEP_BOTTOM_OFFSET); PanelTopVfoB.BringToFront; - PanelTopVfoSep.BringToFront; end; procedure TMainForm.ResizeSMeter; // PanelSMeterRight на главной форме (Parent=Self). // По Y: от самого верха формы до низа PanelSpanButtons (Toolbar+Span = 66px). -// По X: 40% ширины PanelRight, прижат к правому краю. -const - MARGIN = 3; var - FW, FH: Integer; + FW: Integer; RightW: Integer; // ширина PanelRight SMW: Integer; // ширина S-метра SMLeft: Integer; @@ -1852,15 +1847,15 @@ begin RightW := FW - PanelLeft.Width; if RightW < 200 then Exit; - // Ширина S-метра = 40% от PanelRight - SMW := Round(RightW * 0.40); + // Ширина S-метра = 32% от PanelRight + SMW := Round(RightW * SMETER_WIDTH_RATIO); // X: прижат к правому краю формы - SMLeft := FW - SMW - MARGIN; + SMLeft := FW - SMW - SMETER_MARGIN; // Y: от верха формы+margin до низа PanelSpanButtons-margin - SMTop := MARGIN; - SMBot := PanelToolbar.Height + PanelSpanButtons.Height - MARGIN; + SMTop := SMETER_MARGIN; + SMBot := PanelToolbar.Height + PanelSpanButtons.Height - SMETER_MARGIN; PanelSMeterRight.SetBounds(SMLeft, SMTop, SMW, SMBot - SMTop); PanelSMeterRight.BringToFront; diff --git a/SpectrumView.pas b/SpectrumView.pas index 71ba861..7b5d468 100644 --- a/SpectrumView.pas +++ b/SpectrumView.pas @@ -931,14 +931,15 @@ const CLR_SCALE_S_GREEN = TColor($00E0E0E0); CLR_SCALE_S_BLUE = TColor($0090D090); CLR_BDR = TColor($00303028); - LEFT_INFO = 62; TICK_LONG = 5; TICK_MED = 3; + LEFT_INFO_MIN = 62; RIGHT_PAD = 8; LABEL_PAD = 4; + TICK_LONG = 5; TICK_MED = 3; var - W, H, BX, BW: Integer; + W, H, BX, BW, LeftInfo: Integer; Y_BAR_TOP, Y_BAR_BOT: Integer; BarEnd, PeakLeft, PeakRight, S9X, OvrX: Integer; i, X, TW: Integer; Lbl: string; SNum, Over: Integer; LblDbm, LblS: string; - TWDbm, TWS, TWUnit, LblZoneL, TH10, TH6, MaxTWDbm: Integer; + TWDbm, LblZoneL, TH10, TH6, MaxTWDbm, MaxTWS, LabelNeed: Integer; function DBtoX(dB: Double): Integer; inline; begin @@ -962,7 +963,34 @@ begin W := R.Right - R.Left; H := R.Bottom - R.Top; ZX1 := 0; ZX2 := 0; ZY1 := 0; ZY2 := 0; if (W < 80) or (H < 16) then Exit; - BX := R.Left + LEFT_INFO; BW := W - LEFT_INFO - 8; + + // --- Вычисляем строки надписей заранее чтобы измерить ширину --- + LblDbm := Format('%.1f', [Value]); + if Value >= -73.0 then + begin + Over := Round(Value - (-73.0)); + if Over < 5 then LblS := 'S9' + else begin Over := ((Over + 5) div 10) * 10; if Over = 0 then Over := 10; LblS := Format('S9+%d', [Over]); end; + end else if Value <= -121.0 then LblS := 'S1' + else begin + LblS := 'S1'; + for SNum := 1 to 8 do + if Value >= (-121.0 + (SNum - 1) * 6.0) then LblS := 'S' + IntToStr(SNum); + end; + + // Измеряем ширину надписей + ACanvas.Font.Name := 'Courier New'; ACanvas.Font.Style := [fsBold]; + ACanvas.Font.Size := 10; TWDbm := ACanvas.TextWidth(LblDbm); + MaxTWDbm := ACanvas.TextWidth('-120.0'); + MaxTWS := ACanvas.TextWidth('S9+60'); + ACanvas.Font.Size := 6; ACanvas.Font.Style := []; + // Левая информационная зона зависит от реальных метрик шрифта. + LabelNeed := Max(MaxTWDbm + 2 + ACanvas.TextWidth('dBm '), MaxTWS) + LABEL_PAD * 2; + LeftInfo := Max(LEFT_INFO_MIN, LabelNeed + 4); + BX := R.Left + LeftInfo; BW := W - LeftInfo - RIGHT_PAD; + if BW < 10 then Exit; + LblZoneL := BX - LabelNeed; + Y_BAR_TOP := R.Top + H * 44 div 100; Y_BAR_BOT := R.Top + H * 58 div 100; S9X := DBtoX(DB_S9); OvrX := DBtoX(DB_OVR); @@ -996,27 +1024,6 @@ begin ACanvas.LineTo(PeakRight, Y_BAR_BOT + (Y_BAR_BOT - Y_BAR_TOP)); ACanvas.Pen.Width := 1; end; - // --- Вычисляем строки надписей заранее чтобы измерить ширину --- - LblDbm := Format('%.1f', [Value]); - if Value >= -73.0 then - begin - Over := Round(Value - (-73.0)); - if Over < 5 then LblS := 'S9' - else begin Over := ((Over + 5) div 10) * 10; if Over = 0 then Over := 10; LblS := Format('S9+%d', [Over]); end; - end else if Value <= -121.0 then LblS := 'S1' - else begin - LblS := 'S1'; - for SNum := 1 to 8 do - if Value >= (-121.0 + (SNum - 1) * 6.0) then LblS := 'S' + IntToStr(SNum); - end; - - // Измеряем ширину надписей - ACanvas.Font.Name := 'Courier New'; ACanvas.Font.Style := [fsBold]; - ACanvas.Font.Size := 10; TWDbm := ACanvas.TextWidth(LblDbm); TWS := ACanvas.TextWidth(LblS); - MaxTWDbm := ACanvas.TextWidth('-120.0'); - ACanvas.Font.Size := 6; ACanvas.Font.Style := []; TWUnit := ACanvas.TextWidth('dBm'); - // Левый край зоны: фиксированная ширина под макс. число + "dBm " с пробелом справа - LblZoneL := BX - 4 - Max(MaxTWDbm + 2 + ACanvas.TextWidth('dBm '), TWS) - 4; // Рамка: от левого края зоны надписей до правого края шкалы ACanvas.Brush.Style := bsClear; ACanvas.Pen.Color := CLR_BDR;