Chris@58: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@0: Chris@0: /* Chris@59: Sonic Visualiser Chris@59: An audio file viewer and annotation editor. Chris@59: Centre for Digital Music, Queen Mary, University of London. Chris@0: Chris@59: This program is free software; you can redistribute it and/or Chris@59: modify it under the terms of the GNU General Public License as Chris@59: published by the Free Software Foundation; either version 2 of the Chris@59: License, or (at your option) any later version. See the file Chris@59: COPYING included with this distribution for more information. Chris@0: */ Chris@0: Chris@0: /** Chris@0: * Horizontal audio fader and meter widget. Chris@0: * Chris@0: * Based on the vertical fader and meter widget from the Hydrogen drum Chris@0: * machine. (Any poor taste that has crept in during the Chris@0: * modifications for this application is entirely my own, however.) Chris@0: * The following copyright notice applies to code from this file, and Chris@0: * also to the files in icons/fader_*.png (also modified by me). --cc Chris@0: */ Chris@0: Chris@0: /** Chris@0: * Hydrogen Chris@0: * Copyright(c) 2002-2005 by Alex >Comix< Cominu [comix@users.sourceforge.net] Chris@0: * http://www.hydrogen-music.org Chris@0: */ Chris@0: Chris@0: Chris@0: #include "Fader.h" Chris@0: Chris@0: #include "base/AudioLevel.h" Chris@0: Chris@0: #include Chris@0: #include Chris@0: #include Chris@0: #include Chris@0: #include Chris@187: #include Chris@187: Chris@187: #include Chris@0: Chris@0: Fader::Fader(QWidget *parent, bool withoutKnob) : Chris@0: QWidget(parent), Chris@0: m_withoutKnob(withoutKnob), Chris@0: m_value(1.0), Chris@0: m_peakLeft(0.0), Chris@187: m_peakRight(0.0), Chris@857: m_mousePressed(false), Chris@857: m_mousePressX(0), Chris@857: m_mousePressValue(0) Chris@0: { Chris@0: setMinimumSize(116, 23); Chris@0: setMaximumSize(116, 23); Chris@0: resize(116, 23); Chris@0: Chris@0: QString background_path = ":/icons/fader_background.png"; Chris@0: bool ok = m_back.load(background_path); Chris@0: if (ok == false) { Chris@1266: cerr << "Fader: Error loading pixmap" << endl; Chris@0: } Chris@0: Chris@0: QString leds_path = ":/icons/fader_leds.png"; Chris@0: ok = m_leds.load(leds_path); Chris@0: if (ok == false) { Chris@1266: cerr << "Error loading pixmap" << endl; Chris@0: } Chris@0: Chris@0: QString knob_path = ":/icons/fader_knob.png"; Chris@0: ok = m_knob.load(knob_path); Chris@0: if (ok == false) { Chris@1266: cerr << "Error loading pixmap" << endl; Chris@0: } Chris@0: Chris@0: QString clip_path = ":/icons/fader_knob_red.png"; Chris@0: ok = m_clip.load(clip_path); Chris@0: if (ok == false) { Chris@1266: cerr << "Error loading pixmap" << endl; Chris@0: } Chris@0: } Chris@0: Chris@0: Fader::~Fader() Chris@0: { Chris@0: Chris@0: } Chris@0: Chris@0: void Chris@0: Fader::mouseMoveEvent(QMouseEvent *ev) Chris@0: { Chris@141: if (ev->button() == Qt::MidButton) { Chris@187: setValue(1.0); Chris@187: emit valueChanged(1.0); Chris@187: update(); Chris@144: ev->accept(); Chris@141: return; Chris@141: } Chris@187: if (!m_mousePressed) return; Chris@141: Chris@187: int x = ev->x(); Chris@187: int diff = x - m_mousePressX; Chris@187: if (diff == 0) return; Chris@0: Chris@187: int vx = AudioLevel::multiplier_to_fader Chris@187: (m_mousePressValue, getMaxX(), AudioLevel::LongFader); Chris@0: Chris@187: vx += diff; Chris@0: Chris@187: if (vx > getMaxX()) vx = getMaxX(); Chris@187: if (vx < 0) vx = 0; Chris@187: Chris@908: float fval = (float)AudioLevel::fader_to_multiplier Chris@1266: (vx, getMaxX(), AudioLevel::LongFader); Chris@0: Chris@0: setValue(fval); Chris@0: emit valueChanged(fval); Chris@187: ev->accept(); Chris@0: } Chris@0: Chris@0: Chris@0: void Chris@132: Fader::mouseReleaseEvent(QMouseEvent *ev) Chris@132: { Chris@187: if (m_mousePressed) { Chris@187: mouseMoveEvent(ev); Chris@187: m_mousePressed = false; Chris@187: } Chris@132: } Chris@132: Chris@132: void Chris@0: Fader::mouseDoubleClickEvent(QMouseEvent *) Chris@0: { Chris@187: bool ok = false; Chris@908: float min = (float)AudioLevel::fader_to_dB Chris@187: (0, getMaxX(), AudioLevel::LongFader); Chris@908: float max = (float)AudioLevel::fader_to_dB Chris@187: (getMaxX(), getMaxX(), AudioLevel::LongFader); Chris@908: float deft = (float)AudioLevel::multiplier_to_dB(m_value); Chris@187: Chris@908: float dB = (float)QInputDialog::getDouble Chris@187: (this, Chris@187: tr("Enter new fader level"), Chris@187: tr("New fader level, from %1 to %2 dBFS:").arg(min).arg(max), Chris@187: deft, min, max, 3, &ok); Chris@187: Chris@187: if (ok) { Chris@908: float value = (float)AudioLevel::dB_to_multiplier(dB); Chris@187: setValue(value); Chris@187: emit valueChanged(value); Chris@187: update(); Chris@187: } Chris@0: } Chris@0: Chris@0: void Chris@0: Fader::mousePressEvent(QMouseEvent *ev) Chris@0: { Chris@187: if (ev->button() == Qt::MidButton || Chris@187: ((ev->button() == Qt::LeftButton) && Chris@187: (ev->modifiers() & Qt::ControlModifier))) { Chris@82: setValue(1.0); Chris@82: emit valueChanged(1.0); Chris@82: update(); Chris@82: return; Chris@82: } Chris@82: Chris@187: if (ev->button() != Qt::LeftButton) return; Chris@187: m_mousePressed = true; Chris@187: m_mousePressX = ev->x(); Chris@187: m_mousePressValue = getValue(); Chris@0: } Chris@0: Chris@0: Chris@0: void Chris@0: Fader::wheelEvent(QWheelEvent *ev) Chris@0: { Chris@0: ev->accept(); Chris@0: Chris@0: //!!! needs improvement Chris@0: Chris@0: if (ev->delta() > 0) { Chris@1266: setValue(m_value * 1.f); Chris@0: } else { Chris@1266: setValue(m_value / 1.f); Chris@0: } Chris@0: Chris@0: update(); Chris@0: emit valueChanged(getValue()); Chris@0: } Chris@0: Chris@189: void Chris@189: Fader::enterEvent(QEvent *) Chris@189: { Chris@189: emit mouseEntered(); Chris@189: } Chris@189: Chris@189: void Chris@189: Fader::leaveEvent(QEvent *) Chris@189: { Chris@189: emit mouseLeft(); Chris@189: } Chris@0: Chris@0: void Chris@0: Fader::setValue(float v) Chris@0: { Chris@908: float max = (float)AudioLevel::dB_to_multiplier(10.0); Chris@0: Chris@0: if (v > max) { Chris@1266: v = max; Chris@0: } else if (v < 0.0) { Chris@1266: v = 0.0; Chris@0: } Chris@0: Chris@0: if (m_value != v) { Chris@1266: m_value = v; Chris@1266: float db = (float)AudioLevel::multiplier_to_dB(m_value); Chris@187: QString text; Chris@1266: if (db <= AudioLevel::DB_FLOOR) { Chris@187: text = tr("Level: Off"); Chris@1266: } else { Chris@187: text = tr("Level: %1%2.%3%4 dB") Chris@187: .arg(db < 0.0 ? "-" : "") Chris@187: .arg(abs(int(db))) Chris@187: .arg(abs(int(db * 10.0) % 10)) Chris@187: .arg(abs(int(db * 100.0) % 10)); Chris@1266: } Chris@682: cerr << "Fader: setting tooltip to \"" << text << "\"" << endl; Chris@187: QWidget::setToolTip(text); Chris@1266: update(); Chris@0: } Chris@0: } Chris@0: Chris@0: Chris@0: float Chris@0: Fader::getValue() Chris@0: { Chris@0: return m_value; Chris@0: } Chris@0: Chris@0: Chris@0: Chris@0: void Chris@0: Fader::setPeakLeft(float peak) Chris@0: { Chris@0: if (this->m_peakLeft != peak) { Chris@1266: this->m_peakLeft = peak; Chris@1266: update(); Chris@0: } Chris@0: } Chris@0: Chris@0: Chris@0: void Chris@0: Fader::setPeakRight(float peak) Chris@0: { Chris@0: if (this->m_peakRight != peak) { Chris@1266: this->m_peakRight = peak; Chris@1266: update(); Chris@0: } Chris@0: } Chris@0: Chris@0: Chris@0: void Chris@0: Fader::paintEvent(QPaintEvent *) Chris@0: { Chris@0: QPainter painter(this); Chris@0: Chris@0: // background Chris@0: painter.drawPixmap(rect(), m_back, QRect(0, 0, 116, 23)); Chris@0: Chris@0: int offset_L = AudioLevel::multiplier_to_fader(m_peakLeft, 116, Chris@1266: AudioLevel::IEC268LongMeter); Chris@0: Chris@0: painter.drawPixmap(QRect(0, 0, offset_L, 11), m_leds, Chris@1266: QRect(0, 0, offset_L, 11)); Chris@0: Chris@0: int offset_R = AudioLevel::multiplier_to_fader(m_peakRight, 116, Chris@1266: AudioLevel::IEC268LongMeter); Chris@0: Chris@0: painter.drawPixmap(QRect(0, 11, offset_R, 11), m_leds, Chris@1266: QRect(0, 11, offset_R, 11)); Chris@0: Chris@0: if (m_withoutKnob == false) { Chris@0: Chris@1266: static const uint knob_width = 29; Chris@1266: static const uint knob_height = 9; Chris@0: Chris@1266: int x = AudioLevel::multiplier_to_fader(m_value, 116 - knob_width, Chris@1266: AudioLevel::LongFader); Chris@0: Chris@1266: bool clipping = (m_peakLeft > 1.0 || m_peakRight > 1.0); Chris@0: Chris@1266: painter.drawPixmap(QRect(x, 7, knob_width, knob_height), Chris@1266: clipping ? m_clip : m_knob, Chris@1266: QRect(0, 0, knob_width, knob_height)); Chris@0: } Chris@0: } Chris@0: Chris@187: int Chris@187: Fader::getMaxX() const Chris@187: { Chris@187: return 116 - 12; Chris@187: }