UI: Use selective repaint on volume meter scale
Fix for issue 3915 - reduce tick and font blur at 125% DPI. Former use of paint cache resulted in blur when scaled.
This commit is contained in:
parent
dd564a2e8f
commit
c8a0dbff1e
@ -683,7 +683,6 @@ VolumeMeter::VolumeMeter(QWidget *parent, obs_volmeter_t *obs_volmeter,
|
||||
VolumeMeter::~VolumeMeter()
|
||||
{
|
||||
updateTimerRef->RemoveVolControl(this);
|
||||
delete tickPaintCache;
|
||||
}
|
||||
|
||||
void VolumeMeter::setLevels(const float magnitude[MAX_AUDIO_CHANNELS],
|
||||
@ -899,11 +898,11 @@ void VolumeMeter::paintVTicks(QPainter &painter, int x, int y, int height)
|
||||
QString str = QString::number(i);
|
||||
|
||||
if (i == 0)
|
||||
painter.drawText(x + 5, position + 4, str);
|
||||
painter.drawText(x + 5, position + 5, str);
|
||||
else if (i == -60)
|
||||
painter.drawText(x + 4, position, str);
|
||||
painter.drawText(x + 4, position + 1, str);
|
||||
else
|
||||
painter.drawText(x + 4, position + 2, str);
|
||||
painter.drawText(x + 4, position + 3, str);
|
||||
painter.drawLine(x, position, x + 2, position);
|
||||
}
|
||||
|
||||
@ -1151,58 +1150,38 @@ void VolumeMeter::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
uint64_t ts = os_gettime_ns();
|
||||
qreal timeSinceLastRedraw = (ts - lastRedrawTime) * 0.000000001;
|
||||
|
||||
const QRect rect = event->region().boundingRect();
|
||||
int width = rect.width();
|
||||
int height = rect.height();
|
||||
|
||||
handleChannelCofigurationChange();
|
||||
calculateBallistics(ts, timeSinceLastRedraw);
|
||||
bool idle = detectIdle(ts);
|
||||
|
||||
// Draw the ticks in a off-screen buffer when the widget changes size.
|
||||
QSize tickPaintCacheSize;
|
||||
if (vertical)
|
||||
tickPaintCacheSize = QSize(14, height);
|
||||
else
|
||||
tickPaintCacheSize = QSize(width, 9);
|
||||
if (tickPaintCache == nullptr ||
|
||||
tickPaintCache->size() != tickPaintCacheSize) {
|
||||
delete tickPaintCache;
|
||||
tickPaintCache = new QPixmap(tickPaintCacheSize);
|
||||
QRect widgetRect = rect();
|
||||
int width = widgetRect.width();
|
||||
int height = widgetRect.height();
|
||||
|
||||
QColor clearColor(0, 0, 0, 0);
|
||||
tickPaintCache->fill(clearColor);
|
||||
|
||||
QPainter tickPainter(tickPaintCache);
|
||||
if (vertical) {
|
||||
tickPainter.translate(0, height);
|
||||
tickPainter.scale(1, -1);
|
||||
paintVTicks(tickPainter, 0, 11,
|
||||
tickPaintCacheSize.height() - 11);
|
||||
} else {
|
||||
paintHTicks(tickPainter, 6, 0,
|
||||
tickPaintCacheSize.width() - 6,
|
||||
tickPaintCacheSize.height());
|
||||
}
|
||||
tickPainter.end();
|
||||
}
|
||||
|
||||
// Actual painting of the widget starts here.
|
||||
QPainter painter(this);
|
||||
|
||||
// Paint window background color (as widget is opaque)
|
||||
QColor background = palette().color(QPalette::ColorRole::Window);
|
||||
painter.fillRect(rect, background);
|
||||
// timerEvent requests update of the bar(s) only, so we can avoid the
|
||||
// overhead of repainting the scale and labels
|
||||
if (event->region().boundingRect() != getBarRect()) {
|
||||
handleChannelCofigurationChange();
|
||||
|
||||
// Paint window background color (as widget is opaque)
|
||||
QColor background =
|
||||
palette().color(QPalette::ColorRole::Window);
|
||||
painter.fillRect(widgetRect, background);
|
||||
|
||||
if (vertical) {
|
||||
paintVTicks(painter, displayNrAudioChannels * 4 - 1, 1,
|
||||
height - 6);
|
||||
} else {
|
||||
paintHTicks(painter, 6, displayNrAudioChannels * 4 - 1,
|
||||
width - 6, height);
|
||||
}
|
||||
}
|
||||
|
||||
if (vertical) {
|
||||
// Invert the Y axis to ease the math
|
||||
painter.translate(0, height);
|
||||
painter.scale(1, -1);
|
||||
painter.drawPixmap(displayNrAudioChannels * 4 - 1, 7,
|
||||
*tickPaintCache);
|
||||
} else {
|
||||
painter.drawPixmap(0, height - 9, *tickPaintCache);
|
||||
}
|
||||
|
||||
for (int channelNr = 0; channelNr < displayNrAudioChannels;
|
||||
@ -1214,7 +1193,7 @@ void VolumeMeter::paintEvent(QPaintEvent *event)
|
||||
: channelNr;
|
||||
|
||||
if (vertical)
|
||||
paintVMeter(painter, channelNr * 4, 8, 3, height - 10,
|
||||
paintVMeter(painter, channelNr * 4, 5, 3, height - 5,
|
||||
displayMagnitude[channelNrFixed],
|
||||
displayPeak[channelNrFixed],
|
||||
displayPeakHold[channelNrFixed]);
|
||||
@ -1231,7 +1210,7 @@ void VolumeMeter::paintEvent(QPaintEvent *event)
|
||||
// see that the audio stream has been stopped, without
|
||||
// having too much visual impact.
|
||||
if (vertical)
|
||||
paintInputMeter(painter, channelNr * 4, 3, 3, 3,
|
||||
paintInputMeter(painter, channelNr * 4, 0, 3, 3,
|
||||
displayInputPeakHold[channelNrFixed]);
|
||||
else
|
||||
paintInputMeter(painter, 0, channelNr * 4, 3, 3,
|
||||
@ -1241,6 +1220,16 @@ void VolumeMeter::paintEvent(QPaintEvent *event)
|
||||
lastRedrawTime = ts;
|
||||
}
|
||||
|
||||
QRect VolumeMeter::getBarRect()
|
||||
{
|
||||
QRect rec = rect();
|
||||
if (vertical)
|
||||
rec.setWidth(displayNrAudioChannels * 4);
|
||||
else
|
||||
rec.setHeight(displayNrAudioChannels * 4);
|
||||
return rec;
|
||||
}
|
||||
|
||||
void VolumeMeterTimer::AddVolControl(VolumeMeter *meter)
|
||||
{
|
||||
volumeMeters.push_back(meter);
|
||||
@ -1253,6 +1242,7 @@ void VolumeMeterTimer::RemoveVolControl(VolumeMeter *meter)
|
||||
|
||||
void VolumeMeterTimer::timerEvent(QTimerEvent *)
|
||||
{
|
||||
// Tell paintEvent to paint only the bars, leaving the scale alone.
|
||||
for (VolumeMeter *meter : volumeMeters)
|
||||
meter->update();
|
||||
meter->update(meter->getBarRect());
|
||||
}
|
||||
|
@ -123,7 +123,6 @@ private:
|
||||
float currentPeak[MAX_AUDIO_CHANNELS];
|
||||
float currentInputPeak[MAX_AUDIO_CHANNELS];
|
||||
|
||||
QPixmap *tickPaintCache = nullptr;
|
||||
int displayNrAudioChannels = 0;
|
||||
float displayMagnitude[MAX_AUDIO_CHANNELS];
|
||||
float displayPeak[MAX_AUDIO_CHANNELS];
|
||||
@ -176,6 +175,7 @@ public:
|
||||
void setLevels(const float magnitude[MAX_AUDIO_CHANNELS],
|
||||
const float peak[MAX_AUDIO_CHANNELS],
|
||||
const float inputPeak[MAX_AUDIO_CHANNELS]);
|
||||
QRect getBarRect();
|
||||
|
||||
QColor getBackgroundNominalColor() const;
|
||||
void setBackgroundNominalColor(QColor c);
|
||||
|
Loading…
x
Reference in New Issue
Block a user