summaryrefslogtreecommitdiff
path: root/muse2/awl/mslider.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'muse2/awl/mslider.cpp')
-rw-r--r--muse2/awl/mslider.cpp273
1 files changed, 273 insertions, 0 deletions
diff --git a/muse2/awl/mslider.cpp b/muse2/awl/mslider.cpp
new file mode 100644
index 00000000..63c3ea4e
--- /dev/null
+++ b/muse2/awl/mslider.cpp
@@ -0,0 +1,273 @@
+//=============================================================================
+// Awl
+// Audio Widget Library
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// 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.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "fastlog.h"
+
+#include "mslider.h"
+
+namespace Awl {
+
+//---------------------------------------------------------
+// MeterSlider
+//---------------------------------------------------------
+
+MeterSlider::MeterSlider(QWidget* parent)
+ : VolSlider(parent)
+ {
+ setAttribute(Qt::WA_NoSystemBackground, true);
+// setAutoFillBackground(true);
+ _channel = 0;
+ yellowScale = -16; //-10;
+ redScale = 0;
+ _meterWidth = _scaleWidth * 3;
+ setChannel(1);
+ setMinimumHeight(50);
+ }
+
+//---------------------------------------------------------
+// sizeHint
+//---------------------------------------------------------
+
+QSize MeterSlider::sizeHint() const
+ {
+ int w = _meterWidth + _scaleWidth + _scaleWidth + 30;
+ return orientation() == Qt::Vertical ? QSize(w, 200) : QSize(200, w);
+ }
+
+//---------------------------------------------------------
+// setChannel
+//---------------------------------------------------------
+
+void MeterSlider::setChannel(int n)
+ {
+ if (n > _channel) {
+ for (int i = _channel; i < n; ++i) {
+ meterval.push_back(0.0f);
+ meterPeak.push_back(0.0f);
+ }
+ }
+ _channel = n;
+ }
+
+//---------------------------------------------------------
+// setMeterVal
+//---------------------------------------------------------
+
+void MeterSlider::setMeterVal(int channel, double v, double peak)
+ {
+ bool mustRedraw = false;
+ if (meterval[channel] != v) {
+ meterval[channel] = v;
+ mustRedraw = true;
+ }
+ if (peak != meterPeak[channel]) {
+ meterPeak[channel] = peak;
+ mustRedraw = true;
+ }
+ if (mustRedraw) {
+ int kh = sliderSize().height();
+ int mh = height() - kh;
+ update(20, kh / 2, _meterWidth-1, mh);
+ }
+ }
+
+//---------------------------------------------------------
+// resetPeaks
+// reset peak and overflow indicator
+//---------------------------------------------------------
+
+void MeterSlider::resetPeaks()
+ {
+ for (int i = 0; i < _channel; ++i)
+ meterPeak[i] = meterval[i];
+ update();
+ }
+
+//---------------------------------------------------------
+// resizeEvent
+//---------------------------------------------------------
+
+void MeterSlider::resizeEvent(QResizeEvent* /*ev*/)
+ {
+ int h = height();
+ int kh = sliderSize().height();
+ int mh = h - kh;
+ int mw = _meterWidth / _channel;
+
+ onPm = QPixmap(mw, mh);
+ offPm = QPixmap(mw, mh);
+
+ double range = maxValue() - minValue();
+ int h1 = mh - lrint((maxValue() - redScale) * mh / range);
+ int h2 = mh - lrint((maxValue() - yellowScale) * mh / range);
+
+ QColor yellowRed;
+ yellowRed.setHsv(QColor(Qt::yellow).hue()-8,
+ QColor(Qt::yellow).saturation(),
+ QColor(Qt::yellow).value());
+ QColor yellRedRed;
+ yellRedRed.setHsv(QColor(Qt::yellow).hue()-16,
+ QColor(Qt::yellow).saturation(),
+ QColor(Qt::yellow).value());
+
+ QLinearGradient linearGrad(QPointF(0, 0), QPointF(0, mh));
+ linearGrad.setColorAt(0, Qt::red);
+ linearGrad.setColorAt(1-(double)(h1-5)/(double)mh, yellRedRed);
+ linearGrad.setColorAt(1-(double)(h1-6)/(double)mh, yellowRed);
+ linearGrad.setColorAt(1-(double)h2/(double)mh, Qt::yellow);
+ linearGrad.setColorAt(1, Qt::green);
+
+ QColor darkYellowRed;
+ darkYellowRed.setHsv(QColor(Qt::darkYellow).hue()-8,
+ QColor(Qt::darkYellow).saturation(),
+ QColor(Qt::darkYellow).value());
+ QColor darkYellRedRed;
+ darkYellRedRed.setHsv(QColor(Qt::darkYellow).hue()-16,
+ QColor(Qt::darkYellow).saturation(),
+ QColor(Qt::darkYellow).value());
+ QLinearGradient linearDarkGrad(QPointF(0, 0), QPointF(0, mh));
+ linearDarkGrad.setColorAt(0, Qt::darkRed);
+ linearDarkGrad.setColorAt(1-(double)(h1-5)/(double)mh, darkYellRedRed);
+ linearDarkGrad.setColorAt(1-(double)(h1-6)/(double)mh, darkYellowRed);
+ linearDarkGrad.setColorAt(1-(double)h2/(double)mh, Qt::darkYellow);
+ linearDarkGrad.setColorAt(1, Qt::darkGreen);
+
+ QPainter p;
+ p.begin(&onPm);
+ p.fillRect(0, 0, mw, mh, linearGrad);
+ p.end();
+ p.begin(&offPm);
+ p.fillRect(0, 0, mw, mh, linearDarkGrad);
+ p.end();
+ }
+
+//---------------------------------------------------------
+// paintEvent
+//---------------------------------------------------------
+
+void MeterSlider::paintEvent(QPaintEvent* ev)
+ {
+ int pixel = height() - sliderSize().height();
+ double range = maxValue() - minValue();
+ int ppos = int(pixel * (_value - minValue()) / range);
+ if (_invert)
+ ppos = pixel - ppos;
+
+ QPainter p(this);
+ p.setRenderHint(QPainter::Antialiasing, false);
+
+ int h = height();
+ int kh = sliderSize().height();
+
+ //---------------------------------------------------
+ // draw meter
+ //---------------------------------------------------
+
+ int mw = _meterWidth / _channel;
+ int x = 20;
+ int y1 = kh / 2;
+ int y3 = h - y1;
+
+ int mh = h - kh;
+ p.setPen(QPen(Qt::white, 2));
+
+ for (int i = 0; i < _channel; ++i) {
+ int h = mh - (lrint(fast_log10(meterval[i]) * -20.0f * mh / range));
+ if (h < 0)
+ h = 0;
+ else if (h > mh)
+ h = mh;
+
+ p.drawPixmap(x, y1+mh-h, mw, h, onPm, 0, y1+mh-h, mw, h);
+ p.drawPixmap(x, y1, mw, mh-h, offPm, 0, y1, mw, mh-h);
+
+ //---------------------------------------------------
+ // draw peak line
+ //---------------------------------------------------
+
+ h = mh - (lrint(fast_log10(meterPeak[i]) * -20.0f * mh / range));
+ if (h > mh)
+ h = mh;
+ if (h > 0)
+ p.drawLine(x, y3-h, x+mw, y3-h);
+
+ x += mw;
+ }
+
+ // optimize common case:
+ if (ev->rect() == QRect(20, kh/2, _meterWidth-1, mh))
+ return;
+
+ QColor sc(isEnabled() ? _scaleColor : Qt::gray);
+ QColor svc(isEnabled() ? _scaleValueColor : Qt::gray);
+ p.setBrush(svc);
+
+ //---------------------------------------------------
+ // draw scale
+ //---------------------------------------------------
+
+ int y2 = h - (ppos + y1);
+ p.fillRect(x, y1, _scaleWidth, y2-y1, sc);
+ p.fillRect(x, y2, _scaleWidth, y3-y2, svc);
+
+ //---------------------------------------------------
+ // draw tick marks
+ //---------------------------------------------------
+
+ QFont f(p.font());
+ f.setPointSize(6);
+ p.setFont(f);
+ p.setPen(QPen(Qt::darkGray, 2));
+ QFontMetrics fm(f);
+ int xt = 20 - fm.width("00") - 5;
+
+ QString s;
+ for (int i = 10; i < 70; i += 10) {
+ h = y1 + lrint(i * mh / range);
+ s.setNum(i - 10);
+ p.drawText(xt, h - 3, s);
+ p.drawLine(15, h, 20, h);
+ }
+
+ //---------------------------------------------------
+ // draw slider
+ //---------------------------------------------------
+
+ x += _scaleWidth/2;
+ p.setPen(QPen(svc, 0));
+ p.translate(QPointF(x, y2));
+ p.setRenderHint(QPainter::Antialiasing, true);
+ p.drawPath(*points);
+ }
+
+//---------------------------------------------------------
+// mousePressEvent
+//---------------------------------------------------------
+
+void MeterSlider::mousePressEvent(QMouseEvent* ev)
+ {
+ if (ev->pos().x() < _meterWidth) {
+ emit meterClicked();
+ return;
+ }
+ VolSlider::mousePressEvent(ev);
+ }
+}
+