Cleanup
[carla.git] / source / frontend / widgets / digitalpeakmeter.hpp
bloba324dac839ce61613bfb57ad936fbe34628ad96d
1 /*
2 * Digital Peak Meter, a custom Qt widget
3 * Copyright (C) 2011-2015 Filipe Coelho <falktx@falktx.com>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License, or any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * For a full copy of the GNU General Public License see the doc/GPL.txt file.
18 #ifndef DIGITALPEAKMETER_HPP_INCLUDED
19 #define DIGITALPEAKMETER_HPP_INCLUDED
21 #include "CarlaJuceUtils.hpp"
23 #include <QtGui/QPainter>
24 #include <QtGui/QPaintEvent>
26 #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
27 # include <QtWidgets/QWidget>
28 #else
29 # include <QtGui/QWidget>
30 #endif
32 // ------------------------------------------------------------------------------------------------------------
34 class DigitalPeakMeter : public QWidget
36 public:
37 enum Color {
38 COLOR_GREEN = 1,
39 COLOR_BLUE = 2
42 enum Orientation {
43 HORIZONTAL = 1,
44 VERTICAL = 2
47 enum Style {
48 STYLE_DEFAULT = 1,
49 STYLE_OPENAV = 2,
50 STYLE_RNCBC = 3
53 // --------------------------------------------------------------------------------------------------------
55 DigitalPeakMeter(QWidget* const p)
56 : QWidget(p),
57 fChannelCount(0),
58 fChannelData(nullptr),
59 fLastChannelData(nullptr),
60 fMeterColor(COLOR_GREEN),
61 fMeterColorBase(93, 231, 61),
62 fMeterColorBaseAlt(15, 110, 15, 100),
63 fMeterLinesEnabled(true),
64 fMeterOrientation(VERTICAL),
65 fMeterStyle(STYLE_DEFAULT),
66 fMeterBackground("#111111"),
67 fMeterGradient(0, 0, 0, 0),
68 fSmoothMultiplier(1)
70 updateGrandient();
73 ~DigitalPeakMeter() override
75 if (fChannelData != nullptr)
77 delete[] fChannelData;
78 fChannelData = nullptr;
81 if (fLastChannelData != nullptr)
83 delete[] fLastChannelData;
84 fLastChannelData = nullptr;
88 // --------------------------------------------------------------------------------------------------------
90 int channelCount() const noexcept
92 return fChannelCount;
95 void setChannelCount(const int count)
97 if (fChannelCount == count)
98 return;
100 if (count < 0)
101 return qCritical("DigitalPeakMeter::setChannelCount(%i) - channel count must be a positive integer or zero", count);
103 fChannelCount = count;
104 fChannelData = new float[count];
105 fLastChannelData = new float[count];
107 for (int i=count; --i >= 0;)
109 /**/fChannelData[i] = 0.0f;
110 fLastChannelData[i] = 0.0f;
114 // --------------------------------------------------------------------------------------------------------
116 Color meterColor() const noexcept
118 return fMeterColor;
121 void setMeterColor(const Color color)
123 if (fMeterColor == color)
124 return;
126 if (! QList<Color>({COLOR_GREEN, COLOR_BLUE}).contains(color))
127 return qCritical("DigitalPeakMeter::setMeterColor(%i) - invalid color", color);
129 switch (color)
131 case COLOR_GREEN:
132 fMeterColorBase = QColor(93, 231, 61);
133 fMeterColorBaseAlt = QColor(15, 110, 15, 100);
134 break;
135 case COLOR_BLUE:
136 fMeterColorBase = QColor(82, 238, 248);
137 fMeterColorBaseAlt = QColor(15, 15, 110, 100);
138 break;
141 fMeterColor = color;
143 updateGrandient();
146 // --------------------------------------------------------------------------------------------------------
148 bool meterLinesEnabled() const noexcept
150 return fMeterLinesEnabled;
153 void setMeterLinesEnabled(const bool yesNo)
155 if (fMeterLinesEnabled == yesNo)
156 return;
158 fMeterLinesEnabled = yesNo;
161 // --------------------------------------------------------------------------------------------------------
163 Orientation meterOrientation() const noexcept
165 return fMeterOrientation;
168 void setMeterOrientation(const Orientation orientation)
170 if (fMeterOrientation == orientation)
171 return;
173 if (! QList<Orientation>({HORIZONTAL, VERTICAL}).contains(orientation))
174 return qCritical("DigitalPeakMeter::setMeterOrientation(%i) - invalid orientation", orientation);
176 fMeterOrientation = orientation;
178 updateGrandient();
181 // --------------------------------------------------------------------------------------------------------
183 Style meterStyle() const noexcept
185 return fMeterStyle;
188 void setMeterStyle(const Style style)
190 if (fMeterStyle == style)
191 return;
193 if (! QList<Style>({STYLE_DEFAULT, STYLE_OPENAV, STYLE_RNCBC}).contains(style))
194 return qCritical("DigitalPeakMeter::setMeterStyle(%i) - invalid style", style);
196 switch (style)
198 case STYLE_DEFAULT:
199 fMeterBackground = QColor("#111111");
200 break;
201 case STYLE_OPENAV:
202 fMeterBackground = QColor("#1A1A1A");
203 break;
204 case STYLE_RNCBC:
205 fMeterBackground = QColor("#111111");
206 break;
209 fMeterStyle = style;
211 updateGrandient();
214 // --------------------------------------------------------------------------------------------------------
216 int smoothMultiplier() const noexcept
218 return fSmoothMultiplier;
221 void setSmoothMultiplier(const int value)
223 if (fSmoothMultiplier == value)
224 return;
226 if (value < 0)
227 return qCritical("DigitalPeakMeter::setSmoothMultiplier(%i) - value must be >= 0", value);
228 if (value > 5)
229 return qCritical("DigitalPeakMeter::setSmoothMultiplier(%i) - value must be < 5", value);
231 fSmoothMultiplier = value;
234 // --------------------------------------------------------------------------------------------------------
236 void displayMeter(const int meter, float level, bool forced = false)
238 if (meter <= 0 or meter > fChannelCount)
239 return qCritical("DigitalPeakMeter::displayMeter(%i, %f) - invalid meter number", meter, level);
241 const int i = meter - 1;
243 if (fSmoothMultiplier > 0 && ! forced)
244 level = (fLastChannelData[i] * float(fSmoothMultiplier) + level) / float(fSmoothMultiplier + 1);
246 if (level < 0.001f)
247 level = 0.0f;
248 else if (level > 0.999f)
249 level = 1.0f;
251 if (fChannelData[i] != level)
253 fChannelData[i] = level;
254 update();
257 fLastChannelData[i] = level;
260 // --------------------------------------------------------------------------------------------------------
262 protected:
263 void updateGrandient()
265 fMeterGradient = QLinearGradient(0, 0, 1, 1);
267 if (fMeterStyle == STYLE_OPENAV)
269 fMeterGradient.setColorAt(0.0, fMeterColorBase);
270 fMeterGradient.setColorAt(1.0, fMeterColorBase);
272 else
274 switch (fMeterOrientation)
276 case HORIZONTAL:
277 fMeterGradient.setColorAt(0.0, fMeterColorBase);
278 fMeterGradient.setColorAt(0.2, fMeterColorBase);
279 fMeterGradient.setColorAt(0.4, fMeterColorBase);
280 fMeterGradient.setColorAt(0.6, fMeterColorBase);
281 fMeterGradient.setColorAt(0.8, Qt::yellow);
282 fMeterGradient.setColorAt(1.0, Qt::red);
283 break;
284 case VERTICAL:
285 fMeterGradient.setColorAt(0.0, Qt::red);
286 fMeterGradient.setColorAt(0.2, Qt::yellow);
287 fMeterGradient.setColorAt(0.4, fMeterColorBase);
288 fMeterGradient.setColorAt(0.6, fMeterColorBase);
289 fMeterGradient.setColorAt(0.8, fMeterColorBase);
290 fMeterGradient.setColorAt(1.0, fMeterColorBase);
291 break;
295 updateGrandientFinalStop();
298 void updateGrandientFinalStop()
300 switch (fMeterOrientation)
302 case HORIZONTAL:
303 fMeterGradient.setFinalStop(width(), 0);
304 break;
305 case VERTICAL:
306 fMeterGradient.setFinalStop(0, height());
307 break;
311 // --------------------------------------------------------------------------------------------------------
313 QSize minimumSizeHint() const override
315 return QSize(10, 10);
318 QSize sizeHint() const override
320 return QSize(width(), height());
323 // --------------------------------------------------------------------------------------------------------
325 void paintEvent(QPaintEvent* const ev) override
327 QPainter painter(this);
328 ev->accept();
330 const int width_ = width();
331 const int height_ = height();
333 // draw background
334 painter.setPen(QPen(fMeterBackground, 2));
335 painter.setBrush(fMeterBackground);
336 painter.drawRect(0, 0, width_, height_);
339 // --------------------------------------------------------------------------------------------------------
341 void resizeEvent(QResizeEvent* const ev) override
343 QWidget::resizeEvent(ev);
344 updateGrandientFinalStop();
347 // --------------------------------------------------------------------------------------------------------
349 private:
350 int fChannelCount;
351 float* fChannelData;
352 float* fLastChannelData;
354 Color fMeterColor;
355 QColor fMeterColorBase;
356 QColor fMeterColorBaseAlt;
358 bool fMeterLinesEnabled;
359 Orientation fMeterOrientation;
360 Style fMeterStyle;
362 QColor fMeterBackground;
363 QLinearGradient fMeterGradient;
365 int fSmoothMultiplier;
367 CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(DigitalPeakMeter)
370 // ------------------------------------------------------------------------------------------------------------
372 #endif // DIGITALPEAKMETER_HPP_INCLUDED