31class CPlotter final :
public QWidget {
45 Scaler1D(
int const &avg,
int const &bpp) : m_avg(avg), m_bpp(bpp) {
50 m_scale = 10.0f * std::sqrt(m_bpp * m_avg / 15.0f) *
51 std::pow(10.0f, 0.015f * m_gain);
54 int gain()
const {
return m_gain; }
55 int zero()
const {
return m_zero; }
57 void setGain(
int const gain) {
61 void setZero(
int const zero) { m_zero = zero; }
63 inline auto operator()(
float const value)
const {
64 return std::isnan(value)
66 : std::clamp(m_zero +
static_cast<int>(m_scale * value),
82 Scaler2D(
int const &h2) : m_h2(h2) { rescale(); }
85 m_scaledGain = m_h2 / 70.0f * std::pow(10.0f, 0.02f * m_gain);
86 m_scaledZero = m_h2 * 0.9f - m_h2 / 70.0f * m_zero;
89 int gain()
const {
return m_gain; }
90 int zero()
const {
return m_zero; }
92 void setGain(
int const gain) {
96 void setZero(
int const zero) {
101 inline auto operator()(
float const value)
const {
102 return m_scaledZero - m_scaledGain * value;
107 using Colors = QVector<QColor>;
108 using Spectrum = WF::Spectrum;
110 explicit CPlotter(QWidget *parent =
nullptr);
116 QSize minimumSizeHint()
const override;
117 QSize sizeHint()
const override;
121 int binsPerPixel()
const {
return m_binsPerPixel; }
122 int flatten()
const {
return m_flatten.live(); }
123 int freq()
const {
return m_freq; }
124 int percent2D()
const {
return m_percent2D; }
125 int plot2dGain()
const {
return m_scaler2D.gain(); }
126 int plot2dZero()
const {
return m_scaler2D.zero(); }
127 int plotGain()
const {
return m_scaler1D.gain(); }
128 int plotZero()
const {
return m_scaler1D.zero(); }
129 Spectrum spectrum()
const {
return m_spectrum; }
130 int startFreq()
const {
return m_startFreq; }
132 int frequencyAt(
int const x)
const {
133 return static_cast<int>(freqFromX(x));
138 void setFlatten(
bool const flatten) { m_flatten(flatten); }
139 void setPlot2dGain(
int const plot2dGain) { m_scaler2D.setGain(plot2dGain); }
140 void setPlot2dZero(
int const plot2dZero) { m_scaler2D.setZero(plot2dZero); }
141 void setSpectrum(Spectrum
const spectrum) { m_spectrum = spectrum; }
145 void drawLine(QString
const &);
146 void drawData(WF::SWide, WF::State);
147 void drawDecodeLine(
const QColor &,
int,
int);
148 void drawHorizontalLine(
const QColor &,
int,
int);
149 void setBinsPerPixel(
int);
150 void setColors(Colors
const &);
151 void setDialFreq(
float);
152 void setFilter(
int,
int);
153 void setFilterEnabled(
bool);
154 void setFilterOpacity(
int);
156 void setPercent2D(
int);
157 void setPlotGain(
int);
158 void setPlotZero(
int);
159 void setStartFreq(
int);
160 void setSubMode(
int);
161 void setWaterfallAvg(
int);
165 void changeFreq(
int);
170 void paintEvent(QPaintEvent *)
override;
171 void resizeEvent(QResizeEvent *)
override;
172 void leaveEvent(QEvent *)
override;
173 void wheelEvent(QWheelEvent *)
override;
174 void mouseMoveEvent(QMouseEvent *)
override;
175 void mouseReleaseEvent(QMouseEvent *)
override;
183 using Replot = boost::circular_buffer<
184 std::variant<std::monostate, QString, WF::SWide>>;
188 bool shouldDrawSpectrum(WF::State)
const;
189 bool in30MBand()
const;
190 int xFromFreq(
float f)
const;
191 float freqFromX(
int x)
const;
203 float m_dialFreq = 0.0f;
205 int m_filterCenter = 0;
206 int m_filterWidth = 0;
207 int m_filterOpacity = 127;
209 int m_binsPerPixel = 2;
210 int m_waterfallAvg = 1;
211 int m_lastMouseX = -1;
212 int m_line = std::numeric_limits<int>::max();
218 bool m_filterEnabled =
false;
219 float m_freqPerPixel;
228 Spectrum m_spectrum = Spectrum::Current;
229 QTimer *m_replotTimer;
230 QTimer *m_resizeTimer;
232 QPixmap m_ScalePixmap;
233 QPixmap m_WaterfallPixmap;
234 QPixmap m_OverlayPixmap;
235 QPixmap m_SpectrumPixmap;
237 std::array<QPixmap, 2> m_FilterPixmap = {};
238 std::array<QPixmap, 2> m_DialPixmap = {};