66 lines
1.9 KiB
C++
66 lines
1.9 KiB
C++
#include "SpectrumWidget.h"
|
|
#include <QPainter>
|
|
#include <QLinearGradient>
|
|
|
|
SpectrumWidget::SpectrumWidget(int barCount, QWidget* parent)
|
|
: QWidget(parent), _barCount(barCount), _current(barCount, 0), _peak(barCount, 0)
|
|
{
|
|
setFixedSize(100, 26);
|
|
_decayTimer = new QTimer(this);
|
|
_decayTimer->setInterval(33);
|
|
connect(_decayTimer, &QTimer::timeout, this, [this]() {
|
|
bool anyActive = false;
|
|
for (int i = 0; i < _barCount; ++i) {
|
|
_peak[i] *= 0.88f;
|
|
if (_peak[i] < 0.01f) _peak[i] = 0;
|
|
else anyActive = true;
|
|
}
|
|
if (!anyActive) _decayTimer->stop();
|
|
update();
|
|
});
|
|
}
|
|
|
|
void SpectrumWidget::updateLevels(const QVector<float>& levels) {
|
|
for (int i = 0; i < _barCount && i < levels.size(); ++i) {
|
|
_current[i] = levels[i];
|
|
if (levels[i] > _peak[i]) _peak[i] = levels[i];
|
|
}
|
|
if (!_decayTimer->isActive()) _decayTimer->start();
|
|
update();
|
|
}
|
|
|
|
void SpectrumWidget::reset() {
|
|
_current.fill(0);
|
|
_peak.fill(0);
|
|
_decayTimer->stop();
|
|
update();
|
|
}
|
|
|
|
void SpectrumWidget::paintEvent(QPaintEvent*) {
|
|
QPainter p(this);
|
|
p.setRenderHint(QPainter::Antialiasing);
|
|
|
|
int w = width(), h = height();
|
|
qreal gap = 1.5;
|
|
qreal barW = (w - (_barCount - 1) * gap) / _barCount;
|
|
|
|
for (int i = 0; i < _barCount; ++i) {
|
|
qreal x = i * (barW + gap);
|
|
qreal level = qMin(1.0f, _peak[i]);
|
|
qreal barH = qMax(2.0, level * h);
|
|
|
|
QLinearGradient grad(0, h, 0, h - barH);
|
|
if (level > 0.01) {
|
|
grad.setColorAt(0, QColor(94, 179, 230, 200));
|
|
grad.setColorAt(1, QColor(92, 184, 92, 240));
|
|
} else {
|
|
grad.setColorAt(0, QColor(42, 48, 64, 100));
|
|
grad.setColorAt(1, QColor(42, 48, 64, 60));
|
|
}
|
|
|
|
p.setPen(Qt::NoPen);
|
|
p.setBrush(grad);
|
|
p.drawRoundedRect(QRectF(x, h - barH, barW, barH), 1.5, 1.5);
|
|
}
|
|
}
|