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: * Chris@0: * http://www.hydrogen-music.org Chris@0: * Chris@0: * This program is free software; you can redistribute it and/or modify Chris@0: * it under the terms of the GNU General Public License as published by Chris@0: * the Free Software Foundation; either version 2 of the License, or Chris@0: * (at your option) any later version. Chris@0: * Chris@0: * This program is distributed in the hope that it will be useful, Chris@0: * but WITHOUT ANY WARRANTY, without even the implied warranty of Chris@0: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Chris@0: * GNU General Public License for more details. Chris@0: * Chris@0: * You should have received a copy of the GNU General Public License Chris@0: * along with this program; if not, write to the Free Software Chris@0: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 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@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@0: m_peakRight(0.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@0: std::cerr << "Fader: Error loading pixmap" << std::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@0: std::cerr << "Error loading pixmap" << std::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@0: std::cerr << "Error loading pixmap" << std::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@0: std::cerr << "Error loading pixmap" << std::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@0: int x = ev->x() - 6; Chris@0: const int max_x = 116 - 12; Chris@0: Chris@0: int value = x; Chris@0: Chris@0: if (value > max_x) { Chris@0: value = max_x; Chris@0: } else if (value < 0) { Chris@0: value = 0; Chris@0: } Chris@0: Chris@0: // float fval = float(value) / float(max_x); Chris@0: float fval = AudioLevel::fader_to_multiplier Chris@0: (value, max_x, AudioLevel::LongFader); Chris@0: Chris@0: setValue(fval); Chris@0: emit valueChanged(fval); Chris@0: Chris@0: update(); Chris@0: } Chris@0: Chris@0: Chris@0: void Chris@0: Fader::mouseDoubleClickEvent(QMouseEvent *) Chris@0: { Chris@0: setValue(1.0); Chris@0: emit valueChanged(1.0); Chris@0: update(); Chris@0: } Chris@0: Chris@0: void Chris@0: Fader::mousePressEvent(QMouseEvent *ev) Chris@0: { Chris@82: if (ev->button() == Qt::MidButton) { Chris@82: setValue(1.0); Chris@82: emit valueChanged(1.0); Chris@82: update(); Chris@82: return; Chris@82: } Chris@82: Chris@0: int x = ev->x() - 6; Chris@0: const int max_x = 116 - 12; Chris@0: Chris@0: int value = x; Chris@0: Chris@0: if (value > max_x) { Chris@0: value = max_x; Chris@0: } else if (value < 0) { Chris@0: value = 0; Chris@0: } Chris@0: Chris@0: float fval = AudioLevel::fader_to_multiplier Chris@0: (value, max_x, AudioLevel::LongFader); Chris@0: Chris@0: setValue(fval); Chris@0: emit valueChanged(fval); Chris@0: Chris@0: update(); 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@0: setValue(m_value * 1.1); Chris@0: } else { Chris@0: setValue(m_value / 1.1); Chris@0: } Chris@0: Chris@0: update(); Chris@0: emit valueChanged(getValue()); Chris@0: } Chris@0: Chris@0: Chris@0: void Chris@0: Fader::setValue(float v) Chris@0: { Chris@0: float max = AudioLevel::dB_to_multiplier(10.0); Chris@0: Chris@0: if (v > max) { Chris@0: v = max; Chris@0: } else if (v < 0.0) { Chris@0: v = 0.0; Chris@0: } Chris@0: Chris@0: if (m_value != v) { Chris@0: m_value = v; Chris@0: float db = AudioLevel::multiplier_to_dB(m_value); Chris@0: if (db <= AudioLevel::DB_FLOOR) { Chris@0: setToolTip(tr("Level: Off")); Chris@0: } else { Chris@0: setToolTip(tr("Level: %1%2.%3%4 dB") Chris@0: .arg(db < 0.0 ? "-" : "") Chris@0: .arg(abs(int(db))) Chris@0: .arg(abs(int(db * 10.0) % 10)) Chris@0: .arg(abs(int(db * 100.0) % 10))); Chris@0: } Chris@0: 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@0: this->m_peakLeft = peak; Chris@0: 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@0: this->m_peakRight = peak; Chris@0: 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@0: AudioLevel::IEC268LongMeter); Chris@0: Chris@0: painter.drawPixmap(QRect(0, 0, offset_L, 11), m_leds, Chris@0: QRect(0, 0, offset_L, 11)); Chris@0: Chris@0: int offset_R = AudioLevel::multiplier_to_fader(m_peakRight, 116, Chris@0: AudioLevel::IEC268LongMeter); Chris@0: Chris@0: painter.drawPixmap(QRect(0, 11, offset_R, 11), m_leds, Chris@0: QRect(0, 11, offset_R, 11)); Chris@0: Chris@0: if (m_withoutKnob == false) { Chris@0: Chris@0: static const uint knob_width = 29; Chris@0: static const uint knob_height = 9; Chris@0: Chris@0: int x = AudioLevel::multiplier_to_fader(m_value, 116 - knob_width, Chris@0: AudioLevel::LongFader); Chris@0: Chris@0: bool clipping = (m_peakLeft > 1.0 || m_peakRight > 1.0); Chris@0: Chris@0: painter.drawPixmap(QRect(x, 7, knob_width, knob_height), Chris@0: clipping ? m_clip : m_knob, Chris@0: QRect(0, 0, knob_width, knob_height)); Chris@0: } Chris@0: } Chris@0: Chris@0: