|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300 |
- /*
- * Digital Peak Meter, a custom Qt4 widget
- * Copyright (C) 2011-2013 Filipe Coelho <falktx@falktx.com>
- *
- * 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 2 of
- * the License, or 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.
- *
- * For a full copy of the GNU General Public License see the GPL.txt file
- */
-
- #include "digitalpeakmeter.hpp"
-
- #include <QtGui/QPainter>
- #include <QtGui/QPaintEvent>
-
- DigitalPeakMeter::DigitalPeakMeter(QWidget* parent)
- : QWidget(parent),
- fChannels(0),
- fSmoothMultiplier(1),
- fWidth(0),
- fHeight(0),
- fSizeMeter(0),
- fOrientation(VERTICAL),
- fColorBackground("#111111"),
- fGradientMeter(0, 0, 1, 1),
- fColorBase(93, 231, 61),
- fColorBaseAlt(15, 110, 15, 100),
- fChannelsData(nullptr),
- fLastValueData(nullptr),
- fPaintTimer(this)
- {
- setChannels(0);
- setColor(GREEN);
-
- fPaintTimer.setInterval(60);
- connect(&fPaintTimer, SIGNAL(timeout()), this, SLOT(update()));
- fPaintTimer.start();
- }
-
- DigitalPeakMeter::~DigitalPeakMeter()
- {
- if (fChannelsData != nullptr)
- delete[] fChannelsData;
- if (fLastValueData != nullptr)
- delete[] fLastValueData;
- }
-
- void DigitalPeakMeter::displayMeter(int meter, float level)
- {
- Q_ASSERT(fChannelsData != nullptr);
- Q_ASSERT(meter > 0 && meter <= fChannels);
-
- if (meter <= 0 || meter > fChannels || fChannelsData == nullptr)
- return qCritical("DigitalPeakMeter::displayMeter(%i, %f) - invalid meter number", meter, level);
-
- if (level < 0.0f)
- level = -level;
- else if (level > 1.0f)
- level = 1.0f;
-
- fChannelsData[meter-1] = level;
- }
-
- void DigitalPeakMeter::setChannels(int channels)
- {
- Q_ASSERT(channels >= 0);
-
- if (channels < 0)
- return qCritical("DigitalPeakMeter::setChannels(%i) - 'channels' must be a positive integer", channels);
-
- fChannels = channels;
-
- if (fChannelsData != nullptr)
- delete[] fChannelsData;
- if (fLastValueData != nullptr)
- delete[] fLastValueData;
-
- if (channels > 0)
- {
- fChannelsData = new float[channels];
- fLastValueData = new float[channels];
-
- for (int i=0; i < channels; i++)
- {
- fChannelsData[i] = 0.0f;
- fLastValueData[i] = 0.0f;
- }
- }
- else
- {
- fChannelsData = nullptr;
- fLastValueData = nullptr;
- }
- }
-
- void DigitalPeakMeter::setColor(Color color)
- {
- if (color == GREEN)
- {
- fColorBase = QColor(93, 231, 61);
- fColorBaseAlt = QColor(15, 110, 15, 100);
- }
- else if (color == BLUE)
- {
- fColorBase = QColor(82, 238, 248);
- fColorBaseAlt = QColor(15, 15, 110, 100);
- }
- else
- return qCritical("DigitalPeakMeter::setColor(%i) - invalid color", color);
-
- setOrientation(fOrientation);
- }
-
- void DigitalPeakMeter::setOrientation(Orientation orientation)
- {
- fOrientation = orientation;
-
- if (fOrientation == HORIZONTAL)
- {
- fGradientMeter.setColorAt(0.0f, fColorBase);
- fGradientMeter.setColorAt(0.2f, fColorBase);
- fGradientMeter.setColorAt(0.4f, fColorBase);
- fGradientMeter.setColorAt(0.6f, fColorBase);
- fGradientMeter.setColorAt(0.8f, Qt::yellow);
- fGradientMeter.setColorAt(1.0f, Qt::red);
- }
- else if (fOrientation == VERTICAL)
- {
- fGradientMeter.setColorAt(0.0f, Qt::red);
- fGradientMeter.setColorAt(0.2f, Qt::yellow);
- fGradientMeter.setColorAt(0.4f, fColorBase);
- fGradientMeter.setColorAt(0.6f, fColorBase);
- fGradientMeter.setColorAt(0.8f, fColorBase);
- fGradientMeter.setColorAt(1.0f, fColorBase);
- }
- else
- return qCritical("DigitalPeakMeter::setOrientation(%i) - invalid orientation", orientation);
-
- updateSizes();
- }
-
- void DigitalPeakMeter::setRefreshRate(int rate)
- {
- Q_ASSERT(rate > 0);
-
- fPaintTimer.stop();
- fPaintTimer.setInterval(rate);
- fPaintTimer.start();
- }
-
- void DigitalPeakMeter::setSmoothRelease(int value)
- {
- Q_ASSERT(value >= 0 && value <= 5);
-
- if (value < 0)
- value = 0;
- else if (value > 5)
- value = 5;
-
- fSmoothMultiplier = value;
- }
-
- QSize DigitalPeakMeter::minimumSizeHint() const
- {
- return QSize(30, 30);
- }
-
- QSize DigitalPeakMeter::sizeHint() const
- {
- return QSize(fWidth, fHeight);
- }
-
- void DigitalPeakMeter::updateSizes()
- {
- fWidth = width();
- fHeight = height();
- fSizeMeter = 0;
-
- if (fOrientation == HORIZONTAL)
- {
- fGradientMeter.setFinalStop(fWidth, 0);
-
- if (fChannels > 0)
- fSizeMeter = fHeight/fChannels;
- }
- else if (fOrientation == VERTICAL)
- {
- fGradientMeter.setFinalStop(0, fHeight);
-
- if (fChannels > 0)
- fSizeMeter = fWidth/fChannels;
- }
- }
-
- void DigitalPeakMeter::paintEvent(QPaintEvent* event)
- {
- QPainter painter(this);
- event->accept();
-
- painter.setPen(Qt::black);
- painter.setBrush(Qt::black);
- painter.drawRect(0, 0, fWidth, fHeight);
-
- int meterX = 0;
- painter.setPen(fColorBackground);
- painter.setBrush(fGradientMeter);
-
- for (int i=0; i < fChannels; i++)
- {
- float value, level = fChannelsData[i];
-
- if (level == fLastValueData[i])
- continue;
-
- if (fOrientation == HORIZONTAL)
- value = level * float(fWidth);
- else if (fOrientation == VERTICAL)
- value = float(fHeight) - (level * float(fHeight));
- else
- value = 0.0f;
-
- if (value < 0.0f)
- value = 0.0f;
- else if (fSmoothMultiplier > 0)
- value = (fLastValueData[i] * float(fSmoothMultiplier) + value) / float(fSmoothMultiplier + 1);
-
- if (fOrientation == HORIZONTAL)
- painter.drawRect(0, meterX, int(value), fSizeMeter);
- else if (fOrientation == VERTICAL)
- painter.drawRect(meterX, int(value), fSizeMeter, fHeight);
-
- meterX += fSizeMeter;
- fLastValueData[i] = value;
- }
-
- painter.setBrush(Qt::black);
-
- if (fOrientation == HORIZONTAL)
- {
- // Variables
- float lsmall = fWidth;
- float lfull = fHeight - 1;
-
- // Base
- painter.setPen(fColorBaseAlt);
- painter.drawLine(lsmall * 0.25f, 2, lsmall * 0.25f, lfull-2.0f);
- painter.drawLine(lsmall * 0.50f, 2, lsmall * 0.50f, lfull-2.0f);
-
- // Yellow
- painter.setPen(QColor(110, 110, 15, 100));
- painter.drawLine(lsmall * 0.70f, 2, lsmall * 0.70f, lfull-2.0f);
- painter.drawLine(lsmall * 0.83f, 2, lsmall * 0.83f, lfull-2.0f);
-
- // Orange
- painter.setPen(QColor(180, 110, 15, 100));
- painter.drawLine(lsmall * 0.90f, 2, lsmall * 0.90f, lfull-2.0f);
-
- // Red
- painter.setPen(QColor(110, 15, 15, 100));
- painter.drawLine(lsmall * 0.96f, 2, lsmall * 0.96f, lfull-2.0f);
-
- }
- else if (fOrientation == VERTICAL)
- {
- // Variables
- float lsmall = fHeight;
- float lfull = fWidth - 1;
-
- // Base
- painter.setPen(fColorBaseAlt);
- painter.drawLine(2, lsmall - (lsmall * 0.25f), lfull-2.0f, lsmall - (lsmall * 0.25f));
- painter.drawLine(2, lsmall - (lsmall * 0.50f), lfull-2.0f, lsmall - (lsmall * 0.50f));
-
- // Yellow
- painter.setPen(QColor(110, 110, 15, 100));
- painter.drawLine(2, lsmall - (lsmall * 0.70f), lfull-2.0f, lsmall - (lsmall * 0.70f));
- painter.drawLine(2, lsmall - (lsmall * 0.83f), lfull-2.0f, lsmall - (lsmall * 0.83f));
-
- // Orange
- painter.setPen(QColor(180, 110, 15, 100));
- painter.drawLine(2, lsmall - (lsmall * 0.90f), lfull-2.0f, lsmall - (lsmall * 0.90f));
-
- // Red
- painter.setPen(QColor(110, 15, 15, 100));
- painter.drawLine(2, lsmall - (lsmall * 0.96f), lfull-2.0f, lsmall - (lsmall * 0.96f));
- }
- }
-
- void DigitalPeakMeter::resizeEvent(QResizeEvent* event)
- {
- updateSizes();
- QWidget::resizeEvent(event);
- }
|