annotate widgets/Fader.cpp @ 77:fd348f36c0d3

* Implement harmonic cursor in spectrogram * Implement layer export. This doesn't quite do the right thing for the SV XML layer export yet -- it doesn't include layer display information, so when imported, it only creates an invisible model. Could also do with fixing CSV file import so as to work correctly for note and text layers.
author Chris Cannam
date Mon, 10 Apr 2006 17:22:59 +0000
parents 705f05ab42e3
children 82482231b6b1
rev   line source
Chris@58 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@0 2
Chris@0 3 /*
Chris@59 4 Sonic Visualiser
Chris@59 5 An audio file viewer and annotation editor.
Chris@59 6 Centre for Digital Music, Queen Mary, University of London.
Chris@0 7
Chris@59 8 This program is free software; you can redistribute it and/or
Chris@59 9 modify it under the terms of the GNU General Public License as
Chris@59 10 published by the Free Software Foundation; either version 2 of the
Chris@59 11 License, or (at your option) any later version. See the file
Chris@59 12 COPYING included with this distribution for more information.
Chris@0 13 */
Chris@0 14
Chris@0 15 /**
Chris@0 16 * Horizontal audio fader and meter widget.
Chris@0 17 *
Chris@0 18 * Based on the vertical fader and meter widget from the Hydrogen drum
Chris@0 19 * machine. (Any poor taste that has crept in during the
Chris@0 20 * modifications for this application is entirely my own, however.)
Chris@0 21 * The following copyright notice applies to code from this file, and
Chris@0 22 * also to the files in icons/fader_*.png (also modified by me). --cc
Chris@0 23 */
Chris@0 24
Chris@0 25 /**
Chris@0 26 * Hydrogen
Chris@0 27 * Copyright(c) 2002-2005 by Alex >Comix< Cominu [comix@users.sourceforge.net]
Chris@0 28 *
Chris@0 29 * http://www.hydrogen-music.org
Chris@0 30 *
Chris@0 31 * This program is free software; you can redistribute it and/or modify
Chris@0 32 * it under the terms of the GNU General Public License as published by
Chris@0 33 * the Free Software Foundation; either version 2 of the License, or
Chris@0 34 * (at your option) any later version.
Chris@0 35 *
Chris@0 36 * This program is distributed in the hope that it will be useful,
Chris@0 37 * but WITHOUT ANY WARRANTY, without even the implied warranty of
Chris@0 38 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Chris@0 39 * GNU General Public License for more details.
Chris@0 40 *
Chris@0 41 * You should have received a copy of the GNU General Public License
Chris@0 42 * along with this program; if not, write to the Free Software
Chris@0 43 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Chris@0 44 */
Chris@0 45
Chris@0 46
Chris@0 47 #include "Fader.h"
Chris@0 48
Chris@0 49 #include "base/AudioLevel.h"
Chris@0 50
Chris@0 51 #include <QMouseEvent>
Chris@0 52 #include <QPixmap>
Chris@0 53 #include <QWheelEvent>
Chris@0 54 #include <QPaintEvent>
Chris@0 55 #include <QPainter>
Chris@0 56
Chris@0 57 Fader::Fader(QWidget *parent, bool withoutKnob) :
Chris@0 58 QWidget(parent),
Chris@0 59 m_withoutKnob(withoutKnob),
Chris@0 60 m_value(1.0),
Chris@0 61 m_peakLeft(0.0),
Chris@0 62 m_peakRight(0.0)
Chris@0 63 {
Chris@0 64 setMinimumSize(116, 23);
Chris@0 65 setMaximumSize(116, 23);
Chris@0 66 resize(116, 23);
Chris@0 67
Chris@0 68 QString background_path = ":/icons/fader_background.png";
Chris@0 69 bool ok = m_back.load(background_path);
Chris@0 70 if (ok == false) {
Chris@0 71 std::cerr << "Fader: Error loading pixmap" << std::endl;
Chris@0 72 }
Chris@0 73
Chris@0 74 QString leds_path = ":/icons/fader_leds.png";
Chris@0 75 ok = m_leds.load(leds_path);
Chris@0 76 if (ok == false) {
Chris@0 77 std::cerr << "Error loading pixmap" << std::endl;
Chris@0 78 }
Chris@0 79
Chris@0 80 QString knob_path = ":/icons/fader_knob.png";
Chris@0 81 ok = m_knob.load(knob_path);
Chris@0 82 if (ok == false) {
Chris@0 83 std::cerr << "Error loading pixmap" << std::endl;
Chris@0 84 }
Chris@0 85
Chris@0 86 QString clip_path = ":/icons/fader_knob_red.png";
Chris@0 87 ok = m_clip.load(clip_path);
Chris@0 88 if (ok == false) {
Chris@0 89 std::cerr << "Error loading pixmap" << std::endl;
Chris@0 90 }
Chris@0 91 }
Chris@0 92
Chris@0 93 Fader::~Fader()
Chris@0 94 {
Chris@0 95
Chris@0 96 }
Chris@0 97
Chris@0 98 void
Chris@0 99 Fader::mouseMoveEvent(QMouseEvent *ev)
Chris@0 100 {
Chris@0 101 int x = ev->x() - 6;
Chris@0 102 const int max_x = 116 - 12;
Chris@0 103
Chris@0 104 int value = x;
Chris@0 105
Chris@0 106 if (value > max_x) {
Chris@0 107 value = max_x;
Chris@0 108 } else if (value < 0) {
Chris@0 109 value = 0;
Chris@0 110 }
Chris@0 111
Chris@0 112 // float fval = float(value) / float(max_x);
Chris@0 113 float fval = AudioLevel::fader_to_multiplier
Chris@0 114 (value, max_x, AudioLevel::LongFader);
Chris@0 115
Chris@0 116 setValue(fval);
Chris@0 117 emit valueChanged(fval);
Chris@0 118
Chris@0 119 update();
Chris@0 120 }
Chris@0 121
Chris@0 122
Chris@0 123 void
Chris@0 124 Fader::mouseDoubleClickEvent(QMouseEvent *)
Chris@0 125 {
Chris@0 126 setValue(1.0);
Chris@0 127 emit valueChanged(1.0);
Chris@0 128 update();
Chris@0 129 }
Chris@0 130
Chris@0 131 void
Chris@0 132 Fader::mousePressEvent(QMouseEvent *ev)
Chris@0 133 {
Chris@0 134 int x = ev->x() - 6;
Chris@0 135 const int max_x = 116 - 12;
Chris@0 136
Chris@0 137 int value = x;
Chris@0 138
Chris@0 139 if (value > max_x) {
Chris@0 140 value = max_x;
Chris@0 141 } else if (value < 0) {
Chris@0 142 value = 0;
Chris@0 143 }
Chris@0 144
Chris@0 145 float fval = AudioLevel::fader_to_multiplier
Chris@0 146 (value, max_x, AudioLevel::LongFader);
Chris@0 147
Chris@0 148 setValue(fval);
Chris@0 149 emit valueChanged(fval);
Chris@0 150
Chris@0 151 update();
Chris@0 152 }
Chris@0 153
Chris@0 154
Chris@0 155 void
Chris@0 156 Fader::wheelEvent(QWheelEvent *ev)
Chris@0 157 {
Chris@0 158 ev->accept();
Chris@0 159
Chris@0 160 //!!! needs improvement
Chris@0 161
Chris@0 162 if (ev->delta() > 0) {
Chris@0 163 setValue(m_value * 1.1);
Chris@0 164 } else {
Chris@0 165 setValue(m_value / 1.1);
Chris@0 166 }
Chris@0 167
Chris@0 168 update();
Chris@0 169 emit valueChanged(getValue());
Chris@0 170 }
Chris@0 171
Chris@0 172
Chris@0 173 void
Chris@0 174 Fader::setValue(float v)
Chris@0 175 {
Chris@0 176 float max = AudioLevel::dB_to_multiplier(10.0);
Chris@0 177
Chris@0 178 if (v > max) {
Chris@0 179 v = max;
Chris@0 180 } else if (v < 0.0) {
Chris@0 181 v = 0.0;
Chris@0 182 }
Chris@0 183
Chris@0 184 if (m_value != v) {
Chris@0 185 m_value = v;
Chris@0 186 float db = AudioLevel::multiplier_to_dB(m_value);
Chris@0 187 if (db <= AudioLevel::DB_FLOOR) {
Chris@0 188 setToolTip(tr("Level: Off"));
Chris@0 189 } else {
Chris@0 190 setToolTip(tr("Level: %1%2.%3%4 dB")
Chris@0 191 .arg(db < 0.0 ? "-" : "")
Chris@0 192 .arg(abs(int(db)))
Chris@0 193 .arg(abs(int(db * 10.0) % 10))
Chris@0 194 .arg(abs(int(db * 100.0) % 10)));
Chris@0 195 }
Chris@0 196 update();
Chris@0 197 }
Chris@0 198 }
Chris@0 199
Chris@0 200
Chris@0 201 float
Chris@0 202 Fader::getValue()
Chris@0 203 {
Chris@0 204 return m_value;
Chris@0 205 }
Chris@0 206
Chris@0 207
Chris@0 208
Chris@0 209 void
Chris@0 210 Fader::setPeakLeft(float peak)
Chris@0 211 {
Chris@0 212 if (this->m_peakLeft != peak) {
Chris@0 213 this->m_peakLeft = peak;
Chris@0 214 update();
Chris@0 215 }
Chris@0 216 }
Chris@0 217
Chris@0 218
Chris@0 219 void
Chris@0 220 Fader::setPeakRight(float peak)
Chris@0 221 {
Chris@0 222 if (this->m_peakRight != peak) {
Chris@0 223 this->m_peakRight = peak;
Chris@0 224 update();
Chris@0 225 }
Chris@0 226 }
Chris@0 227
Chris@0 228
Chris@0 229 void
Chris@0 230 Fader::paintEvent(QPaintEvent *)
Chris@0 231 {
Chris@0 232 QPainter painter(this);
Chris@0 233
Chris@0 234 // background
Chris@0 235 painter.drawPixmap(rect(), m_back, QRect(0, 0, 116, 23));
Chris@0 236
Chris@0 237 int offset_L = AudioLevel::multiplier_to_fader(m_peakLeft, 116,
Chris@0 238 AudioLevel::IEC268LongMeter);
Chris@0 239
Chris@0 240 painter.drawPixmap(QRect(0, 0, offset_L, 11), m_leds,
Chris@0 241 QRect(0, 0, offset_L, 11));
Chris@0 242
Chris@0 243 int offset_R = AudioLevel::multiplier_to_fader(m_peakRight, 116,
Chris@0 244 AudioLevel::IEC268LongMeter);
Chris@0 245
Chris@0 246 painter.drawPixmap(QRect(0, 11, offset_R, 11), m_leds,
Chris@0 247 QRect(0, 11, offset_R, 11));
Chris@0 248
Chris@0 249 if (m_withoutKnob == false) {
Chris@0 250
Chris@0 251 static const uint knob_width = 29;
Chris@0 252 static const uint knob_height = 9;
Chris@0 253
Chris@0 254 int x = AudioLevel::multiplier_to_fader(m_value, 116 - knob_width,
Chris@0 255 AudioLevel::LongFader);
Chris@0 256
Chris@0 257 bool clipping = (m_peakLeft > 1.0 || m_peakRight > 1.0);
Chris@0 258
Chris@0 259 painter.drawPixmap(QRect(x, 7, knob_width, knob_height),
Chris@0 260 clipping ? m_clip : m_knob,
Chris@0 261 QRect(0, 0, knob_width, knob_height));
Chris@0 262 }
Chris@0 263 }
Chris@0 264
Chris@0 265