kopia lustrzana https://github.com/PianetaRadio/CatRadio
405 wiersze
10 KiB
C++
405 wiersze
10 KiB
C++
/**
|
|
** This file is part of the CatRadio project.
|
|
** Copyright 2022 Gianfranco Sordetti IZ8EWD <iz8ewd@pianetaradio.it>.
|
|
**
|
|
** This program is free software: you can redistribute it and/or modify
|
|
** it under the terms of the GNU General Public License as published by
|
|
** the Free Software Foundation, either version 3 of the License, or
|
|
** (at your option) any later version.
|
|
**
|
|
** This program is distributed in the hope that it will be useful,
|
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
** GNU General Public License for more details.
|
|
**
|
|
** You should have received a copy of the GNU General Public License
|
|
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
**/
|
|
|
|
|
|
#include "smeter.h"
|
|
#include <QPainter>
|
|
#include <math.h>
|
|
|
|
SMeter::SMeter(QWidget *parent) : QWidget(parent)
|
|
{
|
|
lineColor = QColor(Qt::black);
|
|
bgColor = QColor(Qt::white);
|
|
progressColor = QColor(Qt::green);
|
|
scaleColor = QColor(Qt::black);
|
|
|
|
//Default value
|
|
minValue = 0;
|
|
maxValue = 100;
|
|
gateValue = 80;
|
|
longStep = 20;
|
|
shortStep = 10;
|
|
precision = 0;
|
|
|
|
meterTx = false;
|
|
|
|
currentValue = minValue;
|
|
peakValue = minValue;
|
|
peakFactor = 0.1;
|
|
|
|
peakHold = true;
|
|
}
|
|
|
|
void SMeter::paintEvent(QPaintEvent *)
|
|
{
|
|
QPainter painter(this);
|
|
painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
|
|
|
|
QFont font;
|
|
font = painter.font();
|
|
font.setPointSize(font.pointSize() - 2);
|
|
painter.setFont(font);
|
|
|
|
drawMeter(&painter);
|
|
drawProgress(&painter);
|
|
if (peakHold) drawPeak(&painter);
|
|
drawScaleSMeter(&painter);
|
|
drawScalePWRMeter(&painter);
|
|
}
|
|
|
|
void SMeter::drawMeter(QPainter *painter)
|
|
{
|
|
painter->save();
|
|
|
|
QPen pen(lineColor, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
|
|
painter->setPen(pen);
|
|
painter->setBrush(bgColor);
|
|
painter->drawRect(0, height()/3+2, width()-12, height()/3-4);
|
|
painter->restore();
|
|
}
|
|
|
|
void SMeter::drawProgress(QPainter *painter)
|
|
{
|
|
double max, min;
|
|
double gate;
|
|
|
|
painter->save();
|
|
painter->setPen(Qt::NoPen);
|
|
painter->setBrush(progressColor);
|
|
|
|
if (meterTx) //RF power meter
|
|
{
|
|
max = maxValue;
|
|
min = minValue;
|
|
gate = gateValue;
|
|
}
|
|
else //SMeter
|
|
{
|
|
max = 60;
|
|
min = -54;
|
|
gate = 0;
|
|
}
|
|
|
|
double length = width()-14;
|
|
double increment = length / (max - min);
|
|
double initX, initXX;
|
|
|
|
if (currentValue>max) currentValue = max;
|
|
|
|
if (currentValue>gate)
|
|
{
|
|
initX = (gate - min) * increment;
|
|
QRect rect(1, height()/3+2+1, initX, height()/3-4-2);
|
|
painter->drawRect(rect);
|
|
|
|
//Red bar
|
|
initXX = (currentValue - gate) * increment;
|
|
QRect rect2(initX+1, height()/3+2+1, initXX, height()/3-4-2);
|
|
painter->setBrush(Qt::red);
|
|
painter->drawRect(rect2);
|
|
}
|
|
else
|
|
{
|
|
initX = (currentValue - min) * increment;
|
|
QRect rect(1, height()/3+2+1, initX, height()/3-4-2);
|
|
painter->drawRect(rect);
|
|
}
|
|
|
|
painter->restore();
|
|
}
|
|
|
|
void SMeter::drawPeak(QPainter *painter)
|
|
{
|
|
double max, min;
|
|
double gate;
|
|
|
|
painter->save();
|
|
painter->setPen(Qt::NoPen);
|
|
|
|
if (meterTx) //RF power meter
|
|
{
|
|
max = maxValue;
|
|
min = minValue;
|
|
gate = gateValue;
|
|
}
|
|
else //SMeter
|
|
{
|
|
max = 60;
|
|
min = -54;
|
|
gate = 0;
|
|
}
|
|
|
|
double length = width()-14;
|
|
double increment = length / (max - min);
|
|
double initX;
|
|
|
|
if (currentValue>=peakValue) peakValue = currentValue;
|
|
else peakValue = peakValue - peakFactor*(peakValue - currentValue);
|
|
if (peakValue>max) peakValue = max;
|
|
|
|
if (peakValue>gate) painter->setBrush(QColor(Qt::red));
|
|
else painter->setBrush(progressColor);
|
|
|
|
initX = (peakValue - min) * increment;
|
|
|
|
QRect rect(initX - 2, height()/3+2+1, 2, height()/3-4-2);
|
|
painter->drawRect(rect);
|
|
|
|
painter->restore();
|
|
}
|
|
|
|
void SMeter::drawScalePWRMeter(QPainter *painter)
|
|
{
|
|
painter->save();
|
|
painter->setPen(scaleColor);
|
|
|
|
double initX = 0;
|
|
double initTopY = height()*2/3-2;
|
|
double length = width()-12;
|
|
double increment = length / (maxValue - minValue);
|
|
|
|
int longLineLen = 6;
|
|
int shortLineLen = 3;
|
|
|
|
QFontMetrics meterFont(painter->font());
|
|
double textHeight = meterFont.height();
|
|
|
|
//Draw scale and scale values based on range values Long lines
|
|
int stepNumber = (maxValue - minValue) / shortStep;
|
|
for (int i = 0; i <= stepNumber; i++)
|
|
{
|
|
double j = i * shortStep + minValue;
|
|
if (fmod(j,longStep) == 0)
|
|
{
|
|
if (j == minValue) //Do not draw the first value
|
|
{
|
|
QPointF textPot = QPointF(initX, initTopY + textHeight);
|
|
painter->drawText(textPot, "PO");
|
|
|
|
initX += increment * shortStep;
|
|
continue;
|
|
}
|
|
|
|
QPointF topPot = QPointF(initX, initTopY);
|
|
QPointF bottomPot = QPointF(initX, initTopY + longLineLen);
|
|
painter->drawLine(topPot, bottomPot);
|
|
|
|
QString strValue = QString("%1").arg(j, 0, 'f', precision);
|
|
double textWidth = fontMetrics().horizontalAdvance(strValue);
|
|
|
|
QPointF textPot = QPointF(initX - textWidth / 2, initTopY + textHeight + longLineLen - 2);
|
|
painter->drawText(textPot, strValue);
|
|
}
|
|
else
|
|
{
|
|
|
|
QPointF topPot = QPointF(initX, initTopY);
|
|
QPointF bottomPot = QPointF(initX, initTopY + shortLineLen);
|
|
painter->drawLine(topPot, bottomPot);
|
|
}
|
|
|
|
initX += increment * shortStep;
|
|
}
|
|
|
|
painter->restore();
|
|
}
|
|
|
|
void SMeter::drawScaleSMeter(QPainter *painter)
|
|
{
|
|
int minValue = -54; //Set min and max value according to Hamlib SMeter definition
|
|
int maxValue = 60;
|
|
|
|
int longLineLen = 6;
|
|
int shortLineLen = 3;
|
|
|
|
double initX = 0;
|
|
int sUnit = 0;
|
|
|
|
double initBottomY = height()/3+2;
|
|
double length = width()-12;
|
|
double increment = length / (maxValue - minValue);
|
|
|
|
QFontMetrics meterFont(painter->font());
|
|
double textHeight = meterFont.height();
|
|
|
|
painter->save();
|
|
painter->setPen(scaleColor);
|
|
|
|
//Draw scale and scale values based on range values
|
|
int longStep = 12;
|
|
int shortStep = 6;
|
|
|
|
for (int i = minValue; i <= 0; i = i + shortStep) //S0 to S9
|
|
{
|
|
if (i == minValue)
|
|
{
|
|
QPointF textPot = QPointF(initX, initBottomY - 2);
|
|
painter->drawText(textPot, "S");
|
|
|
|
initX += increment * shortStep;
|
|
sUnit = sUnit + 1;
|
|
continue;
|
|
}
|
|
|
|
if (i % longStep == 0)
|
|
{
|
|
QPointF topPot = QPointF(initX, initBottomY);
|
|
QPointF bottomPot = QPointF(initX, initBottomY - longLineLen);
|
|
painter->drawLine(topPot, bottomPot);
|
|
|
|
QString strValue = QString::number(sUnit);
|
|
double textWidth = fontMetrics().horizontalAdvance(strValue);
|
|
QPointF textPot = QPointF(initX - textWidth / 2, initBottomY - textHeight / 2 - longLineLen + 2);
|
|
painter->drawText(textPot, strValue);
|
|
}
|
|
else
|
|
{
|
|
QPointF topPot = QPointF(initX, initBottomY);
|
|
QPointF bottomPot = QPointF(initX, initBottomY - shortLineLen);
|
|
painter->drawLine(topPot, bottomPot);
|
|
}
|
|
|
|
sUnit = sUnit + 1;
|
|
initX += increment * shortStep;
|
|
}
|
|
initX -= increment * shortStep;
|
|
|
|
shortStep = 10;
|
|
longStep = 20;
|
|
|
|
for (int i = 0; i <= maxValue; i = i + shortStep) //S9+ to S9+60
|
|
{
|
|
if (i % longStep == 0)
|
|
{
|
|
QPointF topPot = QPointF(initX, initBottomY);
|
|
QPointF bottomPot = QPointF(initX, initBottomY - longLineLen);
|
|
painter->drawLine(topPot, bottomPot);
|
|
|
|
if (i == 0) //Do not draw the first value
|
|
{
|
|
initX += increment * shortStep;
|
|
continue;
|
|
}
|
|
|
|
QString strValue = "+" + QString::number(i);
|
|
double textWidth = fontMetrics().horizontalAdvance(strValue);
|
|
|
|
QPointF textPot = QPointF(initX - textWidth / 2, initBottomY - textHeight / 2 - longLineLen + 2);
|
|
painter->drawText(textPot, strValue);
|
|
}
|
|
else
|
|
{
|
|
QPointF topPot = QPointF(initX, initBottomY);
|
|
QPointF bottomPot = QPointF(initX, initBottomY - shortLineLen);
|
|
painter->drawLine(topPot, bottomPot);
|
|
}
|
|
|
|
initX += increment * shortStep;
|
|
}
|
|
|
|
painter->restore();
|
|
}
|
|
|
|
void SMeter::setMinValue(double value)
|
|
{
|
|
minValue = value;
|
|
}
|
|
|
|
void SMeter::setMaxValue(double value)
|
|
{
|
|
maxValue = value;
|
|
update();
|
|
}
|
|
|
|
void SMeter::setGateValue(double value)
|
|
{
|
|
gateValue = value;
|
|
}
|
|
|
|
void SMeter::setLongStep(double value)
|
|
{
|
|
longStep = value;
|
|
}
|
|
|
|
void SMeter::setShortStep(double value)
|
|
{
|
|
shortStep = value;
|
|
}
|
|
|
|
void SMeter::setPrecision(int value)
|
|
{
|
|
precision = value;
|
|
}
|
|
|
|
void SMeter::setBgColor(QColor color)
|
|
{
|
|
bgColor = color;
|
|
}
|
|
|
|
void SMeter::setLineColor(QColor color)
|
|
{
|
|
lineColor = color;
|
|
}
|
|
|
|
void SMeter::setProgressColor(QColor color)
|
|
{
|
|
progressColor = color;
|
|
}
|
|
|
|
void SMeter::setScaleColor(QColor color)
|
|
{
|
|
scaleColor = color;
|
|
}
|
|
|
|
void SMeter::setValue(double value)
|
|
{
|
|
currentValue = value;
|
|
update(1, height()/3+2+1, width()-14, height()/3-4-2);
|
|
}
|
|
|
|
void SMeter::setValue(int value)
|
|
{
|
|
setValue(double(value));
|
|
}
|
|
|
|
void SMeter::setTx(bool Tx)
|
|
{
|
|
meterTx = Tx;
|
|
}
|
|
|
|
bool SMeter::getTx()
|
|
{
|
|
return meterTx;
|
|
}
|
|
|
|
void SMeter::setPeak(bool Peak)
|
|
{
|
|
peakHold = Peak;
|
|
}
|
|
|
|
void SMeter::setPeakFactor(double factor)
|
|
{
|
|
peakFactor = factor;
|
|
}
|
|
|
|
void SMeter::resetPeakValue()
|
|
{
|
|
if (meterTx) peakValue = minValue;
|
|
else peakValue = -54;
|
|
}
|