diff options
Diffstat (limited to 'muse2/awl/mslider.cpp')
-rw-r--r-- | muse2/awl/mslider.cpp | 273 |
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); + } +} + |