UI: Make volume meter tweakable by stylesheet
Replace fixed Arial, 7 px meter scale font with the font used for VolumeMeter/QWidget. Add qproperties for meter bar thickness and a scaling factor for the meter scale numbers. If not specified in a QSS, defaults are 3 pixel bar width and 80% of base font size.master
parent
c8a0dbff1e
commit
6a5a5b4538
|
@ -707,6 +707,13 @@ VolumeMeter {
|
||||||
qproperty-majorTickColor: rgb(239,240,241); /* White */
|
qproperty-majorTickColor: rgb(239,240,241); /* White */
|
||||||
qproperty-minorTickColor: rgb(118,121,124); /* Light Gray */
|
qproperty-minorTickColor: rgb(118,121,124); /* Light Gray */
|
||||||
qproperty-peakDecayRate: 23.4; /* Override of the standard PPM Type I rate. */
|
qproperty-peakDecayRate: 23.4; /* Override of the standard PPM Type I rate. */
|
||||||
|
qproperty-meterThickness: 3;
|
||||||
|
|
||||||
|
/* The meter scale numbers normally use your QWidget font, with size */
|
||||||
|
/* multiplied by meterFontScaling to get a proportionally smaller font. */
|
||||||
|
/* To use a unique font for the numbers, specify font-family and/or */
|
||||||
|
/* font-size here, and set meterFontScaling to 1.0. */
|
||||||
|
qproperty-meterFontScaling: 0.7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1260,7 +1267,7 @@ QCalendarWidget QToolButton:pressed {
|
||||||
|
|
||||||
/* Month Dropdown Menu */
|
/* Month Dropdown Menu */
|
||||||
QCalendarWidget QMenu {
|
QCalendarWidget QMenu {
|
||||||
|
|
||||||
}
|
}
|
||||||
/* Year spinbox */
|
/* Year spinbox */
|
||||||
QCalendarWidget QSpinBox {
|
QCalendarWidget QSpinBox {
|
||||||
|
|
|
@ -583,6 +583,13 @@ VolumeMeter {
|
||||||
qproperty-magnitudeColor: rgb(0,0,0);
|
qproperty-magnitudeColor: rgb(0,0,0);
|
||||||
qproperty-majorTickColor: palette(window-text);
|
qproperty-majorTickColor: palette(window-text);
|
||||||
qproperty-minorTickColor: rgb(122,121,122); /* light */
|
qproperty-minorTickColor: rgb(122,121,122); /* light */
|
||||||
|
qproperty-meterThickness: 3;
|
||||||
|
|
||||||
|
/* The meter scale numbers normally use your QWidget font, with size */
|
||||||
|
/* multiplied by meterFontScaling to get a proportionally smaller font. */
|
||||||
|
/* To use a unique font for the numbers, specify font-family and/or */
|
||||||
|
/* font-size here, and set meterFontScaling to 1.0. */
|
||||||
|
qproperty-meterFontScaling: 0.7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -978,7 +985,7 @@ QCalendarWidget QToolButton:pressed {
|
||||||
|
|
||||||
/* Month Dropdown Menu */
|
/* Month Dropdown Menu */
|
||||||
QCalendarWidget QMenu {
|
QCalendarWidget QMenu {
|
||||||
|
|
||||||
}
|
}
|
||||||
/* Year spinbox */
|
/* Year spinbox */
|
||||||
QCalendarWidget QSpinBox {
|
QCalendarWidget QSpinBox {
|
||||||
|
|
|
@ -831,6 +831,13 @@ VolumeMeter {
|
||||||
qproperty-magnitudeColor: palette(window);
|
qproperty-magnitudeColor: palette(window);
|
||||||
qproperty-majorTickColor: palette(window-text);
|
qproperty-majorTickColor: palette(window-text);
|
||||||
qproperty-minorTickColor: palette(mid);
|
qproperty-minorTickColor: palette(mid);
|
||||||
|
qproperty-meterThickness: 3;
|
||||||
|
|
||||||
|
/* The meter scale numbers normally use your QWidget font, with size */
|
||||||
|
/* multiplied by meterFontScaling to get a proportionally smaller font. */
|
||||||
|
/* To use a unique font for the numbers, specify font-family and/or */
|
||||||
|
/* font-size here, and set meterFontScaling to 1.0. */
|
||||||
|
qproperty-meterFontScaling: 0.7;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************/
|
/*******************/
|
||||||
|
|
|
@ -90,6 +90,13 @@ VolumeMeter {
|
||||||
qproperty-magnitudeColor: rgb(0, 0, 0);
|
qproperty-magnitudeColor: rgb(0, 0, 0);
|
||||||
qproperty-majorTickColor: rgb(0, 0, 0);
|
qproperty-majorTickColor: rgb(0, 0, 0);
|
||||||
qproperty-minorTickColor: rgb(50, 50, 50);
|
qproperty-minorTickColor: rgb(50, 50, 50);
|
||||||
|
qproperty-meterThickness: 3;
|
||||||
|
|
||||||
|
/* The meter scale numbers normally use your QWidget font, with size */
|
||||||
|
/* multiplied by meterFontScaling to get a proportionally smaller font. */
|
||||||
|
/* To use a unique font for the numbers, specify font-family and/or */
|
||||||
|
/* font-size here, and set meterFontScaling to 1.0. */
|
||||||
|
qproperty-meterFontScaling: 0.7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,9 @@ using namespace std;
|
||||||
#define CLAMP(x, min, max) ((x) < (min) ? (min) : ((x) > (max) ? (max) : (x)))
|
#define CLAMP(x, min, max) ((x) < (min) ? (min) : ((x) > (max) ? (max) : (x)))
|
||||||
#define FADER_PRECISION 4096.0
|
#define FADER_PRECISION 4096.0
|
||||||
|
|
||||||
|
// Size of the audio indicator in pixels
|
||||||
|
#define INDICATOR_THICKNESS 3
|
||||||
|
|
||||||
QWeakPointer<VolumeMeterTimer> VolumeMeter::updateTimer;
|
QWeakPointer<VolumeMeterTimer> VolumeMeter::updateTimer;
|
||||||
|
|
||||||
void VolControl::OBSVolumeChanged(void *data, float db)
|
void VolControl::OBSVolumeChanged(void *data, float db)
|
||||||
|
@ -235,6 +238,12 @@ VolControl::VolControl(OBSSource source_, bool showConfig, bool vertical)
|
||||||
|
|
||||||
volMeter->setFocusProxy(slider);
|
volMeter->setFocusProxy(slider);
|
||||||
|
|
||||||
|
// Default size can cause clipping of long names in vertical layout.
|
||||||
|
QFont font = nameLabel->font();
|
||||||
|
QFontInfo info(font);
|
||||||
|
font.setPointSizeF(0.8 * info.pointSizeF());
|
||||||
|
nameLabel->setFont(font);
|
||||||
|
|
||||||
setMaximumWidth(110);
|
setMaximumWidth(110);
|
||||||
} else {
|
} else {
|
||||||
QHBoxLayout *volLayout = new QHBoxLayout;
|
QHBoxLayout *volLayout = new QHBoxLayout;
|
||||||
|
@ -270,12 +279,7 @@ VolControl::VolControl(OBSSource source_, bool showConfig, bool vertical)
|
||||||
|
|
||||||
setLayout(mainLayout);
|
setLayout(mainLayout);
|
||||||
|
|
||||||
QFont font = nameLabel->font();
|
|
||||||
font.setPointSize(font.pointSize() - 1);
|
|
||||||
|
|
||||||
nameLabel->setText(sourceName);
|
nameLabel->setText(sourceName);
|
||||||
nameLabel->setFont(font);
|
|
||||||
volLabel->setFont(font);
|
|
||||||
|
|
||||||
slider->setMinimum(0);
|
slider->setMinimum(0);
|
||||||
slider->setMaximum(int(FADER_PRECISION));
|
slider->setMaximum(int(FADER_PRECISION));
|
||||||
|
@ -493,6 +497,28 @@ void VolumeMeter::setMinorTickColor(QColor c)
|
||||||
minorTickColor = std::move(c);
|
minorTickColor = std::move(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int VolumeMeter::getMeterThickness() const
|
||||||
|
{
|
||||||
|
return meterThickness;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VolumeMeter::setMeterThickness(int v)
|
||||||
|
{
|
||||||
|
meterThickness = v;
|
||||||
|
recalculateLayout = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal VolumeMeter::getMeterFontScaling() const
|
||||||
|
{
|
||||||
|
return meterFontScaling;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VolumeMeter::setMeterFontScaling(qreal v)
|
||||||
|
{
|
||||||
|
meterFontScaling = v;
|
||||||
|
recalculateLayout = true;
|
||||||
|
}
|
||||||
|
|
||||||
qreal VolumeMeter::getMinimumLevel() const
|
qreal VolumeMeter::getMinimumLevel() const
|
||||||
{
|
{
|
||||||
return minimumLevel;
|
return minimumLevel;
|
||||||
|
@ -633,10 +659,7 @@ VolumeMeter::VolumeMeter(QWidget *parent, obs_volmeter_t *obs_volmeter,
|
||||||
{
|
{
|
||||||
setAttribute(Qt::WA_OpaquePaintEvent, true);
|
setAttribute(Qt::WA_OpaquePaintEvent, true);
|
||||||
|
|
||||||
// Use a font that can be rendered small.
|
// Default meter settings, they only show if
|
||||||
tickFont = QFont("Arial");
|
|
||||||
tickFont.setPixelSize(7);
|
|
||||||
// Default meter color settings, they only show if
|
|
||||||
// there is no stylesheet, do not remove.
|
// there is no stylesheet, do not remove.
|
||||||
backgroundNominalColor.setRgb(0x26, 0x7f, 0x26); // Dark green
|
backgroundNominalColor.setRgb(0x26, 0x7f, 0x26); // Dark green
|
||||||
backgroundWarningColor.setRgb(0x7f, 0x7f, 0x26); // Dark yellow
|
backgroundWarningColor.setRgb(0x7f, 0x7f, 0x26); // Dark yellow
|
||||||
|
@ -665,10 +688,12 @@ VolumeMeter::VolumeMeter(QWidget *parent, obs_volmeter_t *obs_volmeter,
|
||||||
magnitudeIntegrationTime = 0.3; // 99% in 300 ms
|
magnitudeIntegrationTime = 0.3; // 99% in 300 ms
|
||||||
peakHoldDuration = 20.0; // 20 seconds
|
peakHoldDuration = 20.0; // 20 seconds
|
||||||
inputPeakHoldDuration = 1.0; // 1 second
|
inputPeakHoldDuration = 1.0; // 1 second
|
||||||
|
meterThickness = 3; // Bar thickness in pixels
|
||||||
|
meterFontScaling =
|
||||||
|
0.7; // Font size for numbers is 70% of Widget's font size
|
||||||
channels = (int)audio_output_get_channels(obs_get_audio());
|
channels = (int)audio_output_get_channels(obs_get_audio());
|
||||||
|
|
||||||
handleChannelCofigurationChange();
|
doLayout();
|
||||||
updateTimerRef = updateTimer.toStrongRef();
|
updateTimerRef = updateTimer.toStrongRef();
|
||||||
if (!updateTimerRef) {
|
if (!updateTimerRef) {
|
||||||
updateTimerRef = QSharedPointer<VolumeMeterTimer>::create();
|
updateTimerRef = QSharedPointer<VolumeMeterTimer>::create();
|
||||||
|
@ -722,23 +747,49 @@ inline void VolumeMeter::resetLevels()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void VolumeMeter::handleChannelCofigurationChange()
|
bool VolumeMeter::needLayoutChange()
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&dataMutex);
|
|
||||||
|
|
||||||
int currentNrAudioChannels = obs_volmeter_get_nr_channels(obs_volmeter);
|
int currentNrAudioChannels = obs_volmeter_get_nr_channels(obs_volmeter);
|
||||||
if (displayNrAudioChannels != currentNrAudioChannels) {
|
if (displayNrAudioChannels != currentNrAudioChannels) {
|
||||||
displayNrAudioChannels = currentNrAudioChannels;
|
displayNrAudioChannels = currentNrAudioChannels;
|
||||||
|
recalculateLayout = true;
|
||||||
// Make room for 3 pixels meter, with one pixel between each.
|
|
||||||
// Then 9/13 pixels for ticks and numbers.
|
|
||||||
if (vertical)
|
|
||||||
setMinimumSize(displayNrAudioChannels * 4 + 14, 130);
|
|
||||||
else
|
|
||||||
setMinimumSize(130, displayNrAudioChannels * 4 + 8);
|
|
||||||
|
|
||||||
resetLevels();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return recalculateLayout;
|
||||||
|
}
|
||||||
|
|
||||||
|
// When this is called from the constructor, obs_volmeter_get_nr_channels returns 1
|
||||||
|
// and Q_PROPERTY settings have not yet been read from the stylesheet.
|
||||||
|
inline void VolumeMeter::doLayout()
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&dataMutex);
|
||||||
|
|
||||||
|
recalculateLayout = false;
|
||||||
|
|
||||||
|
tickFont = font();
|
||||||
|
QFontInfo info(tickFont);
|
||||||
|
tickFont.setPointSizeF(info.pointSizeF() * meterFontScaling);
|
||||||
|
QFontMetrics metrics(tickFont);
|
||||||
|
if (vertical) {
|
||||||
|
// Each meter channel is meterThickness pixels wide, plus one pixel
|
||||||
|
// between channels, but not after the last.
|
||||||
|
// Add 4 pixels for ticks, space to hold our longest label in this font,
|
||||||
|
// and a few pixels before the fader.
|
||||||
|
QRect scaleBounds = metrics.boundingRect("-88");
|
||||||
|
setMinimumSize(displayNrAudioChannels * (meterThickness + 1) -
|
||||||
|
1 + 4 + scaleBounds.width() + 2,
|
||||||
|
130);
|
||||||
|
} else {
|
||||||
|
// Each meter channel is meterThickness pixels high, plus one pixel
|
||||||
|
// between channels, but not after the last.
|
||||||
|
// Add 4 pixels for ticks, and space high enough to hold our label in
|
||||||
|
// this font, presuming that digits don't have descenders.
|
||||||
|
setMinimumSize(130,
|
||||||
|
displayNrAudioChannels * (meterThickness + 1) -
|
||||||
|
1 + 4 + metrics.capHeight());
|
||||||
|
}
|
||||||
|
|
||||||
|
resetLevels();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool VolumeMeter::detectIdle(uint64_t ts)
|
inline bool VolumeMeter::detectIdle(uint64_t ts)
|
||||||
|
@ -856,12 +907,12 @@ void VolumeMeter::paintInputMeter(QPainter &painter, int x, int y, int width,
|
||||||
painter.fillRect(x, y, width, height, color);
|
painter.fillRect(x, y, width, height, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VolumeMeter::paintHTicks(QPainter &painter, int x, int y, int width,
|
void VolumeMeter::paintHTicks(QPainter &painter, int x, int y, int width)
|
||||||
int height)
|
|
||||||
{
|
{
|
||||||
qreal scale = width / minimumLevel;
|
qreal scale = width / minimumLevel;
|
||||||
|
|
||||||
painter.setFont(tickFont);
|
painter.setFont(tickFont);
|
||||||
|
QFontMetrics metrics(tickFont);
|
||||||
painter.setPen(majorTickColor);
|
painter.setPen(majorTickColor);
|
||||||
|
|
||||||
// Draw major tick lines and numeric indicators.
|
// Draw major tick lines and numeric indicators.
|
||||||
|
@ -869,10 +920,18 @@ void VolumeMeter::paintHTicks(QPainter &painter, int x, int y, int width,
|
||||||
int position = int(x + width - (i * scale) - 1);
|
int position = int(x + width - (i * scale) - 1);
|
||||||
QString str = QString::number(i);
|
QString str = QString::number(i);
|
||||||
|
|
||||||
if (i == 0 || i == -5)
|
// Center the number on the tick, but don't overflow
|
||||||
painter.drawText(position - 3, height, str);
|
QRect textBounds = metrics.boundingRect(str);
|
||||||
else
|
int pos;
|
||||||
painter.drawText(position - 5, height, str);
|
if (i == 0) {
|
||||||
|
pos = position - textBounds.width();
|
||||||
|
} else {
|
||||||
|
pos = position - (textBounds.width() / 2);
|
||||||
|
if (pos < 0)
|
||||||
|
pos = 0;
|
||||||
|
}
|
||||||
|
painter.drawText(pos, y + 4 + metrics.capHeight(), str);
|
||||||
|
|
||||||
painter.drawLine(position, y, position, y + 2);
|
painter.drawLine(position, y, position, y + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -890,26 +949,31 @@ void VolumeMeter::paintVTicks(QPainter &painter, int x, int y, int height)
|
||||||
qreal scale = height / minimumLevel;
|
qreal scale = height / minimumLevel;
|
||||||
|
|
||||||
painter.setFont(tickFont);
|
painter.setFont(tickFont);
|
||||||
|
QFontMetrics metrics(tickFont);
|
||||||
painter.setPen(majorTickColor);
|
painter.setPen(majorTickColor);
|
||||||
|
|
||||||
// Draw major tick lines and numeric indicators.
|
// Draw major tick lines and numeric indicators.
|
||||||
for (int i = 0; i >= minimumLevel; i -= 5) {
|
for (int i = 0; i >= minimumLevel; i -= 5) {
|
||||||
int position = y + int((i * scale) - 1);
|
int position = y + int(i * scale);
|
||||||
QString str = QString::number(i);
|
QString str = QString::number(i);
|
||||||
|
|
||||||
if (i == 0)
|
// Center the number on the tick, but don't overflow
|
||||||
painter.drawText(x + 5, position + 5, str);
|
if (i == 0) {
|
||||||
else if (i == -60)
|
painter.drawText(x + 6, position + metrics.capHeight(),
|
||||||
painter.drawText(x + 4, position + 1, str);
|
str);
|
||||||
else
|
} else {
|
||||||
painter.drawText(x + 4, position + 3, str);
|
painter.drawText(x + 4,
|
||||||
|
position + (metrics.capHeight() / 2),
|
||||||
|
str);
|
||||||
|
}
|
||||||
|
|
||||||
painter.drawLine(x, position, x + 2, position);
|
painter.drawLine(x, position, x + 2, position);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw minor tick lines.
|
// Draw minor tick lines.
|
||||||
painter.setPen(minorTickColor);
|
painter.setPen(minorTickColor);
|
||||||
for (int i = 0; i >= minimumLevel; i--) {
|
for (int i = 0; i >= minimumLevel; i--) {
|
||||||
int position = y + int((i * scale) - 1);
|
int position = y + int(i * scale);
|
||||||
if (i % 5 != 0)
|
if (i % 5 != 0)
|
||||||
painter.drawLine(x, position, x + 1, position);
|
painter.drawLine(x, position, x + 1, position);
|
||||||
}
|
}
|
||||||
|
@ -1160,9 +1224,10 @@ void VolumeMeter::paintEvent(QPaintEvent *event)
|
||||||
QPainter painter(this);
|
QPainter painter(this);
|
||||||
|
|
||||||
// timerEvent requests update of the bar(s) only, so we can avoid the
|
// timerEvent requests update of the bar(s) only, so we can avoid the
|
||||||
// overhead of repainting the scale and labels
|
// overhead of repainting the scale and labels.
|
||||||
if (event->region().boundingRect() != getBarRect()) {
|
if (event->region().boundingRect() != getBarRect()) {
|
||||||
handleChannelCofigurationChange();
|
if (needLayoutChange())
|
||||||
|
doLayout();
|
||||||
|
|
||||||
// Paint window background color (as widget is opaque)
|
// Paint window background color (as widget is opaque)
|
||||||
QColor background =
|
QColor background =
|
||||||
|
@ -1170,11 +1235,17 @@ void VolumeMeter::paintEvent(QPaintEvent *event)
|
||||||
painter.fillRect(widgetRect, background);
|
painter.fillRect(widgetRect, background);
|
||||||
|
|
||||||
if (vertical) {
|
if (vertical) {
|
||||||
paintVTicks(painter, displayNrAudioChannels * 4 - 1, 1,
|
paintVTicks(painter,
|
||||||
height - 6);
|
displayNrAudioChannels *
|
||||||
|
(meterThickness + 1) -
|
||||||
|
1,
|
||||||
|
0, height - (INDICATOR_THICKNESS + 3));
|
||||||
} else {
|
} else {
|
||||||
paintHTicks(painter, 6, displayNrAudioChannels * 4 - 1,
|
paintHTicks(painter, INDICATOR_THICKNESS + 3,
|
||||||
width - 6, height);
|
displayNrAudioChannels *
|
||||||
|
(meterThickness + 1) -
|
||||||
|
1,
|
||||||
|
width - (INDICATOR_THICKNESS + 3));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1193,12 +1264,17 @@ void VolumeMeter::paintEvent(QPaintEvent *event)
|
||||||
: channelNr;
|
: channelNr;
|
||||||
|
|
||||||
if (vertical)
|
if (vertical)
|
||||||
paintVMeter(painter, channelNr * 4, 5, 3, height - 5,
|
paintVMeter(painter, channelNr * (meterThickness + 1),
|
||||||
|
INDICATOR_THICKNESS + 2, meterThickness,
|
||||||
|
height - (INDICATOR_THICKNESS + 2),
|
||||||
displayMagnitude[channelNrFixed],
|
displayMagnitude[channelNrFixed],
|
||||||
displayPeak[channelNrFixed],
|
displayPeak[channelNrFixed],
|
||||||
displayPeakHold[channelNrFixed]);
|
displayPeakHold[channelNrFixed]);
|
||||||
else
|
else
|
||||||
paintHMeter(painter, 5, channelNr * 4, width - 5, 3,
|
paintHMeter(painter, INDICATOR_THICKNESS + 2,
|
||||||
|
channelNr * (meterThickness + 1),
|
||||||
|
width - (INDICATOR_THICKNESS + 2),
|
||||||
|
meterThickness,
|
||||||
displayMagnitude[channelNrFixed],
|
displayMagnitude[channelNrFixed],
|
||||||
displayPeak[channelNrFixed],
|
displayPeak[channelNrFixed],
|
||||||
displayPeakHold[channelNrFixed]);
|
displayPeakHold[channelNrFixed]);
|
||||||
|
@ -1210,26 +1286,40 @@ void VolumeMeter::paintEvent(QPaintEvent *event)
|
||||||
// see that the audio stream has been stopped, without
|
// see that the audio stream has been stopped, without
|
||||||
// having too much visual impact.
|
// having too much visual impact.
|
||||||
if (vertical)
|
if (vertical)
|
||||||
paintInputMeter(painter, channelNr * 4, 0, 3, 3,
|
paintInputMeter(painter,
|
||||||
|
channelNr * (meterThickness + 1), 0,
|
||||||
|
meterThickness, INDICATOR_THICKNESS,
|
||||||
displayInputPeakHold[channelNrFixed]);
|
displayInputPeakHold[channelNrFixed]);
|
||||||
else
|
else
|
||||||
paintInputMeter(painter, 0, channelNr * 4, 3, 3,
|
paintInputMeter(painter, 0,
|
||||||
|
channelNr * (meterThickness + 1),
|
||||||
|
INDICATOR_THICKNESS, meterThickness,
|
||||||
displayInputPeakHold[channelNrFixed]);
|
displayInputPeakHold[channelNrFixed]);
|
||||||
}
|
}
|
||||||
|
|
||||||
lastRedrawTime = ts;
|
lastRedrawTime = ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
QRect VolumeMeter::getBarRect()
|
QRect VolumeMeter::getBarRect() const
|
||||||
{
|
{
|
||||||
QRect rec = rect();
|
QRect rec = rect();
|
||||||
if (vertical)
|
if (vertical)
|
||||||
rec.setWidth(displayNrAudioChannels * 4);
|
rec.setWidth(displayNrAudioChannels * (meterThickness + 1) - 1);
|
||||||
else
|
else
|
||||||
rec.setHeight(displayNrAudioChannels * 4);
|
rec.setHeight(displayNrAudioChannels * (meterThickness + 1) -
|
||||||
|
1);
|
||||||
|
|
||||||
return rec;
|
return rec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VolumeMeter::changeEvent(QEvent *e)
|
||||||
|
{
|
||||||
|
if (e->type() == QEvent::StyleChange)
|
||||||
|
recalculateLayout = true;
|
||||||
|
|
||||||
|
QWidget::changeEvent(e);
|
||||||
|
}
|
||||||
|
|
||||||
void VolumeMeterTimer::AddVolControl(VolumeMeter *meter)
|
void VolumeMeterTimer::AddVolControl(VolumeMeter *meter)
|
||||||
{
|
{
|
||||||
volumeMeters.push_back(meter);
|
volumeMeters.push_back(meter);
|
||||||
|
@ -1242,7 +1332,13 @@ void VolumeMeterTimer::RemoveVolControl(VolumeMeter *meter)
|
||||||
|
|
||||||
void VolumeMeterTimer::timerEvent(QTimerEvent *)
|
void VolumeMeterTimer::timerEvent(QTimerEvent *)
|
||||||
{
|
{
|
||||||
// Tell paintEvent to paint only the bars, leaving the scale alone.
|
for (VolumeMeter *meter : volumeMeters) {
|
||||||
for (VolumeMeter *meter : volumeMeters)
|
if (meter->needLayoutChange()) {
|
||||||
meter->update(meter->getBarRect());
|
// Tell paintEvent to update layout and paint everything
|
||||||
|
meter->update();
|
||||||
|
} else {
|
||||||
|
// Tell paintEvent to paint only the bars
|
||||||
|
meter->update(meter->getBarRect());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,6 +60,10 @@ class VolumeMeter : public QWidget {
|
||||||
setMajorTickColor DESIGNABLE true)
|
setMajorTickColor DESIGNABLE true)
|
||||||
Q_PROPERTY(QColor minorTickColor READ getMinorTickColor WRITE
|
Q_PROPERTY(QColor minorTickColor READ getMinorTickColor WRITE
|
||||||
setMinorTickColor DESIGNABLE true)
|
setMinorTickColor DESIGNABLE true)
|
||||||
|
Q_PROPERTY(int meterThickness READ getMeterThickness WRITE
|
||||||
|
setMeterThickness DESIGNABLE true)
|
||||||
|
Q_PROPERTY(qreal meterFontScaling READ getMeterFontScaling WRITE
|
||||||
|
setMeterFontScaling DESIGNABLE true)
|
||||||
|
|
||||||
// Levels are denoted in dBFS.
|
// Levels are denoted in dBFS.
|
||||||
Q_PROPERTY(qreal minimumLevel READ getMinimumLevel WRITE setMinimumLevel
|
Q_PROPERTY(qreal minimumLevel READ getMinimumLevel WRITE setMinimumLevel
|
||||||
|
@ -99,7 +103,7 @@ private:
|
||||||
QSharedPointer<VolumeMeterTimer> updateTimerRef;
|
QSharedPointer<VolumeMeterTimer> updateTimerRef;
|
||||||
|
|
||||||
inline void resetLevels();
|
inline void resetLevels();
|
||||||
inline void handleChannelCofigurationChange();
|
inline void doLayout();
|
||||||
inline bool detectIdle(uint64_t ts);
|
inline bool detectIdle(uint64_t ts);
|
||||||
inline void calculateBallistics(uint64_t ts,
|
inline void calculateBallistics(uint64_t ts,
|
||||||
qreal timeSinceLastRedraw = 0.0);
|
qreal timeSinceLastRedraw = 0.0);
|
||||||
|
@ -110,14 +114,14 @@ private:
|
||||||
int height, float peakHold);
|
int height, float peakHold);
|
||||||
void paintHMeter(QPainter &painter, int x, int y, int width, int height,
|
void paintHMeter(QPainter &painter, int x, int y, int width, int height,
|
||||||
float magnitude, float peak, float peakHold);
|
float magnitude, float peak, float peakHold);
|
||||||
void paintHTicks(QPainter &painter, int x, int y, int width,
|
void paintHTicks(QPainter &painter, int x, int y, int width);
|
||||||
int height);
|
|
||||||
void paintVMeter(QPainter &painter, int x, int y, int width, int height,
|
void paintVMeter(QPainter &painter, int x, int y, int width, int height,
|
||||||
float magnitude, float peak, float peakHold);
|
float magnitude, float peak, float peakHold);
|
||||||
void paintVTicks(QPainter &painter, int x, int y, int height);
|
void paintVTicks(QPainter &painter, int x, int y, int height);
|
||||||
|
|
||||||
QMutex dataMutex;
|
QMutex dataMutex;
|
||||||
|
|
||||||
|
bool recalculateLayout = true;
|
||||||
uint64_t currentLastUpdateTime = 0;
|
uint64_t currentLastUpdateTime = 0;
|
||||||
float currentMagnitude[MAX_AUDIO_CHANNELS];
|
float currentMagnitude[MAX_AUDIO_CHANNELS];
|
||||||
float currentPeak[MAX_AUDIO_CHANNELS];
|
float currentPeak[MAX_AUDIO_CHANNELS];
|
||||||
|
@ -150,6 +154,10 @@ private:
|
||||||
QColor magnitudeColor;
|
QColor magnitudeColor;
|
||||||
QColor majorTickColor;
|
QColor majorTickColor;
|
||||||
QColor minorTickColor;
|
QColor minorTickColor;
|
||||||
|
|
||||||
|
int meterThickness;
|
||||||
|
qreal meterFontScaling;
|
||||||
|
|
||||||
qreal minimumLevel;
|
qreal minimumLevel;
|
||||||
qreal warningLevel;
|
qreal warningLevel;
|
||||||
qreal errorLevel;
|
qreal errorLevel;
|
||||||
|
@ -175,7 +183,8 @@ public:
|
||||||
void setLevels(const float magnitude[MAX_AUDIO_CHANNELS],
|
void setLevels(const float magnitude[MAX_AUDIO_CHANNELS],
|
||||||
const float peak[MAX_AUDIO_CHANNELS],
|
const float peak[MAX_AUDIO_CHANNELS],
|
||||||
const float inputPeak[MAX_AUDIO_CHANNELS]);
|
const float inputPeak[MAX_AUDIO_CHANNELS]);
|
||||||
QRect getBarRect();
|
QRect getBarRect() const;
|
||||||
|
bool needLayoutChange();
|
||||||
|
|
||||||
QColor getBackgroundNominalColor() const;
|
QColor getBackgroundNominalColor() const;
|
||||||
void setBackgroundNominalColor(QColor c);
|
void setBackgroundNominalColor(QColor c);
|
||||||
|
@ -211,6 +220,10 @@ public:
|
||||||
void setMajorTickColor(QColor c);
|
void setMajorTickColor(QColor c);
|
||||||
QColor getMinorTickColor() const;
|
QColor getMinorTickColor() const;
|
||||||
void setMinorTickColor(QColor c);
|
void setMinorTickColor(QColor c);
|
||||||
|
int getMeterThickness() const;
|
||||||
|
void setMeterThickness(int v);
|
||||||
|
qreal getMeterFontScaling() const;
|
||||||
|
void setMeterFontScaling(qreal v);
|
||||||
qreal getMinimumLevel() const;
|
qreal getMinimumLevel() const;
|
||||||
void setMinimumLevel(qreal v);
|
void setMinimumLevel(qreal v);
|
||||||
qreal getWarningLevel() const;
|
qreal getWarningLevel() const;
|
||||||
|
@ -235,6 +248,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void paintEvent(QPaintEvent *event) override;
|
void paintEvent(QPaintEvent *event) override;
|
||||||
|
void changeEvent(QEvent *e) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class VolumeMeterTimer : public QTimer {
|
class VolumeMeterTimer : public QTimer {
|
||||||
|
|
Loading…
Reference in New Issue