|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372 |
- /*
- * Digital Peak Meter, a custom Qt widget
- * Copyright (C) 2011-2015 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 doc/GPL.txt file.
- */
-
- #ifndef DIGITALPEAKMETER_HPP_INCLUDED
- #define DIGITALPEAKMETER_HPP_INCLUDED
-
- #include "CarlaJuceUtils.hpp"
-
- #include <QtGui/QPainter>
- #include <QtGui/QPaintEvent>
-
- #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
- # include <QtWidgets/QWidget>
- #else
- # include <QtGui/QWidget>
- #endif
-
- // ------------------------------------------------------------------------------------------------------------
-
- class DigitalPeakMeter : public QWidget
- {
- public:
- enum Color {
- COLOR_GREEN = 1,
- COLOR_BLUE = 2
- };
-
- enum Orientation {
- HORIZONTAL = 1,
- VERTICAL = 2
- };
-
- enum Style {
- STYLE_DEFAULT = 1,
- STYLE_OPENAV = 2,
- STYLE_RNCBC = 3
- };
-
- // --------------------------------------------------------------------------------------------------------
-
- DigitalPeakMeter(QWidget* const p)
- : QWidget(p),
- fChannelCount(0),
- fChannelData(nullptr),
- fLastChannelData(nullptr),
- fMeterColor(COLOR_GREEN),
- fMeterColorBase(93, 231, 61),
- fMeterColorBaseAlt(15, 110, 15, 100),
- fMeterLinesEnabled(true),
- fMeterOrientation(VERTICAL),
- fMeterStyle(STYLE_DEFAULT),
- fMeterBackground("#111111"),
- fMeterGradient(0, 0, 0, 0),
- fSmoothMultiplier(1)
- {
- updateGrandient();
- }
-
- ~DigitalPeakMeter() override
- {
- if (fChannelData != nullptr)
- {
- delete[] fChannelData;
- fChannelData = nullptr;
- }
-
- if (fLastChannelData != nullptr)
- {
- delete[] fLastChannelData;
- fLastChannelData = nullptr;
- }
- }
-
- // --------------------------------------------------------------------------------------------------------
-
- int channelCount() const noexcept
- {
- return fChannelCount;
- }
-
- void setChannelCount(const int count)
- {
- if (fChannelCount == count)
- return;
-
- if (count < 0)
- return qCritical("DigitalPeakMeter::setChannelCount(%i) - channel count must be a positive integer or zero", count);
-
- fChannelCount = count;
- fChannelData = new float[count];
- fLastChannelData = new float[count];
-
- for (int i=count; --i >= 0;)
- {
- /**/fChannelData[i] = 0.0f;
- fLastChannelData[i] = 0.0f;
- }
- }
-
- // --------------------------------------------------------------------------------------------------------
-
- Color meterColor() const noexcept
- {
- return fMeterColor;
- }
-
- void setMeterColor(const Color color)
- {
- if (fMeterColor == color)
- return;
-
- if (! QList<Color>({COLOR_GREEN, COLOR_BLUE}).contains(color))
- return qCritical("DigitalPeakMeter::setMeterColor(%i) - invalid color", color);
-
- switch (color)
- {
- case COLOR_GREEN:
- fMeterColorBase = QColor(93, 231, 61);
- fMeterColorBaseAlt = QColor(15, 110, 15, 100);
- break;
- case COLOR_BLUE:
- fMeterColorBase = QColor(82, 238, 248);
- fMeterColorBaseAlt = QColor(15, 15, 110, 100);
- break;
- }
-
- fMeterColor = color;
-
- updateGrandient();
- }
-
- // --------------------------------------------------------------------------------------------------------
-
- bool meterLinesEnabled() const noexcept
- {
- return fMeterLinesEnabled;
- }
-
- void setMeterLinesEnabled(const bool yesNo)
- {
- if (fMeterLinesEnabled == yesNo)
- return;
-
- fMeterLinesEnabled = yesNo;
- }
-
- // --------------------------------------------------------------------------------------------------------
-
- Orientation meterOrientation() const noexcept
- {
- return fMeterOrientation;
- }
-
- void setMeterOrientation(const Orientation orientation)
- {
- if (fMeterOrientation == orientation)
- return;
-
- if (! QList<Orientation>({HORIZONTAL, VERTICAL}).contains(orientation))
- return qCritical("DigitalPeakMeter::setMeterOrientation(%i) - invalid orientation", orientation);
-
- fMeterOrientation = orientation;
-
- updateGrandient();
- }
-
- // --------------------------------------------------------------------------------------------------------
-
- Style meterStyle() const noexcept
- {
- return fMeterStyle;
- }
-
- void setMeterStyle(const Style style)
- {
- if (fMeterStyle == style)
- return;
-
- if (! QList<Style>({STYLE_DEFAULT, STYLE_OPENAV, STYLE_RNCBC}).contains(style))
- return qCritical("DigitalPeakMeter::setMeterStyle(%i) - invalid style", style);
-
- switch (style)
- {
- case STYLE_DEFAULT:
- fMeterBackground = QColor("#111111");
- break;
- case STYLE_OPENAV:
- fMeterBackground = QColor("#1A1A1A");
- break;
- case STYLE_RNCBC:
- fMeterBackground = QColor("#111111");
- break;
- }
-
- fMeterStyle = style;
-
- updateGrandient();
- }
-
- // --------------------------------------------------------------------------------------------------------
-
- int smoothMultiplier() const noexcept
- {
- return fSmoothMultiplier;
- }
-
- void setSmoothMultiplier(const int value)
- {
- if (fSmoothMultiplier == value)
- return;
-
- if (value < 0)
- return qCritical("DigitalPeakMeter::setSmoothMultiplier(%i) - value must be >= 0", value);
- if (value > 5)
- return qCritical("DigitalPeakMeter::setSmoothMultiplier(%i) - value must be < 5", value);
-
- fSmoothMultiplier = value;
- }
-
- // --------------------------------------------------------------------------------------------------------
-
- void displayMeter(const int meter, float level, bool forced = false)
- {
- if (meter <= 0 or meter > fChannelCount)
- return qCritical("DigitalPeakMeter::displayMeter(%i, %f) - invalid meter number", meter, level);
-
- const int i = meter - 1;
-
- if (fSmoothMultiplier > 0 && ! forced)
- level = (fLastChannelData[i] * float(fSmoothMultiplier) + level) / float(fSmoothMultiplier + 1);
-
- if (level < 0.001f)
- level = 0.0f;
- else if (level > 0.999f)
- level = 1.0f;
-
- if (fChannelData[i] != level)
- {
- fChannelData[i] = level;
- update();
- }
-
- fLastChannelData[i] = level;
- }
-
- // --------------------------------------------------------------------------------------------------------
-
- protected:
- void updateGrandient()
- {
- fMeterGradient = QLinearGradient(0, 0, 1, 1);
-
- if (fMeterStyle == STYLE_OPENAV)
- {
- fMeterGradient.setColorAt(0.0, fMeterColorBase);
- fMeterGradient.setColorAt(1.0, fMeterColorBase);
- }
- else
- {
- switch (fMeterOrientation)
- {
- case HORIZONTAL:
- fMeterGradient.setColorAt(0.0, fMeterColorBase);
- fMeterGradient.setColorAt(0.2, fMeterColorBase);
- fMeterGradient.setColorAt(0.4, fMeterColorBase);
- fMeterGradient.setColorAt(0.6, fMeterColorBase);
- fMeterGradient.setColorAt(0.8, Qt::yellow);
- fMeterGradient.setColorAt(1.0, Qt::red);
- break;
- case VERTICAL:
- fMeterGradient.setColorAt(0.0, Qt::red);
- fMeterGradient.setColorAt(0.2, Qt::yellow);
- fMeterGradient.setColorAt(0.4, fMeterColorBase);
- fMeterGradient.setColorAt(0.6, fMeterColorBase);
- fMeterGradient.setColorAt(0.8, fMeterColorBase);
- fMeterGradient.setColorAt(1.0, fMeterColorBase);
- break;
- }
- }
-
- updateGrandientFinalStop();
- }
-
- void updateGrandientFinalStop()
- {
- switch (fMeterOrientation)
- {
- case HORIZONTAL:
- fMeterGradient.setFinalStop(width(), 0);
- break;
- case VERTICAL:
- fMeterGradient.setFinalStop(0, height());
- break;
- }
- }
-
- // --------------------------------------------------------------------------------------------------------
-
- QSize minimumSizeHint() const override
- {
- return QSize(10, 10);
- }
-
- QSize sizeHint() const override
- {
- return QSize(width(), height());
- }
-
- // --------------------------------------------------------------------------------------------------------
-
- void paintEvent(QPaintEvent* const ev) override
- {
- QPainter painter(this);
- ev->accept();
-
- const int width_ = width();
- const int height_ = height();
-
- // draw background
- painter.setPen(QPen(fMeterBackground, 2));
- painter.setBrush(fMeterBackground);
- painter.drawRect(0, 0, width_, height_);
- }
-
- // --------------------------------------------------------------------------------------------------------
-
- void resizeEvent(QResizeEvent* const ev) override
- {
- QWidget::resizeEvent(ev);
- updateGrandientFinalStop();
- }
-
- // --------------------------------------------------------------------------------------------------------
-
- private:
- int fChannelCount;
- float* fChannelData;
- float* fLastChannelData;
-
- Color fMeterColor;
- QColor fMeterColorBase;
- QColor fMeterColorBaseAlt;
-
- bool fMeterLinesEnabled;
- Orientation fMeterOrientation;
- Style fMeterStyle;
-
- QColor fMeterBackground;
- QLinearGradient fMeterGradient;
-
- int fSmoothMultiplier;
-
- CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(DigitalPeakMeter)
- };
-
- // ------------------------------------------------------------------------------------------------------------
-
- #endif // DIGITALPEAKMETER_HPP_INCLUDED
|