annotate widgets/Fader.cpp @ 282:d9319859a4cf tip

(none)
author benoitrigolleau
date Fri, 31 Oct 2008 11:00:24 +0000
parents fc9323a41f5a
children
rev   line source
lbajardsilogic@0 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
lbajardsilogic@0 2
lbajardsilogic@0 3 /*
lbajardsilogic@0 4 Sonic Visualiser
lbajardsilogic@0 5 An audio file viewer and annotation editor.
lbajardsilogic@0 6 Centre for Digital Music, Queen Mary, University of London.
lbajardsilogic@0 7
lbajardsilogic@0 8 This program is free software; you can redistribute it and/or
lbajardsilogic@0 9 modify it under the terms of the GNU General Public License as
lbajardsilogic@0 10 published by the Free Software Foundation; either version 2 of the
lbajardsilogic@0 11 License, or (at your option) any later version. See the file
lbajardsilogic@0 12 COPYING included with this distribution for more information.
lbajardsilogic@0 13 */
lbajardsilogic@0 14
lbajardsilogic@0 15 /**
lbajardsilogic@0 16 * Horizontal audio fader and meter widget.
lbajardsilogic@0 17 *
lbajardsilogic@0 18 * Based on the vertical fader and meter widget from the Hydrogen drum
lbajardsilogic@0 19 * machine. (Any poor taste that has crept in during the
lbajardsilogic@0 20 * modifications for this application is entirely my own, however.)
lbajardsilogic@0 21 * The following copyright notice applies to code from this file, and
lbajardsilogic@0 22 * also to the files in icons/fader_*.png (also modified by me). --cc
lbajardsilogic@0 23 */
lbajardsilogic@0 24
lbajardsilogic@0 25 /**
lbajardsilogic@0 26 * Hydrogen
lbajardsilogic@0 27 * Copyright(c) 2002-2005 by Alex >Comix< Cominu [comix@users.sourceforge.net]
lbajardsilogic@0 28 * http://www.hydrogen-music.org
lbajardsilogic@0 29 */
lbajardsilogic@0 30
lbajardsilogic@0 31
lbajardsilogic@0 32 #include "Fader.h"
lbajardsilogic@0 33
lbajardsilogic@0 34 #include "base/AudioLevel.h"
lbajardsilogic@0 35
lbajardsilogic@0 36 #include <QMouseEvent>
lbajardsilogic@0 37 #include <QPixmap>
lbajardsilogic@0 38 #include <QWheelEvent>
lbajardsilogic@0 39 #include <QPaintEvent>
lbajardsilogic@0 40 #include <QPainter>
lbajardsilogic@0 41 #include <QInputDialog>
lbajardsilogic@0 42
lbajardsilogic@0 43 #include <iostream>
lbajardsilogic@0 44
lbajardsilogic@0 45 Fader::Fader(QWidget *parent, bool withoutKnob) :
lbajardsilogic@0 46 QWidget(parent),
lbajardsilogic@0 47 m_withoutKnob(withoutKnob),
lbajardsilogic@0 48 m_value(1.0),
lbajardsilogic@0 49 m_peakLeft(0.0),
lbajardsilogic@0 50 m_peakRight(0.0),
lbajardsilogic@0 51 m_mousePressed(false)
lbajardsilogic@0 52 {
lbajardsilogic@0 53 setMinimumSize(116, 23);
lbajardsilogic@0 54 setMaximumSize(116, 23);
lbajardsilogic@0 55 resize(116, 23);
lbajardsilogic@0 56
lbajardsilogic@0 57 QString background_path = ":/icons/fader_background.png";
lbajardsilogic@0 58 bool ok = m_back.load(background_path);
lbajardsilogic@0 59 if (ok == false) {
lbajardsilogic@0 60 std::cerr << "Fader: Error loading pixmap" << std::endl;
lbajardsilogic@0 61 }
lbajardsilogic@0 62
lbajardsilogic@0 63 QString leds_path = ":/icons/fader_leds.png";
lbajardsilogic@0 64 ok = m_leds.load(leds_path);
lbajardsilogic@0 65 if (ok == false) {
lbajardsilogic@0 66 std::cerr << "Error loading pixmap" << std::endl;
lbajardsilogic@0 67 }
lbajardsilogic@0 68
lbajardsilogic@0 69 QString knob_path = ":/icons/fader_knob.png";
lbajardsilogic@0 70 ok = m_knob.load(knob_path);
lbajardsilogic@0 71 if (ok == false) {
lbajardsilogic@0 72 std::cerr << "Error loading pixmap" << std::endl;
lbajardsilogic@0 73 }
lbajardsilogic@0 74
lbajardsilogic@0 75 QString clip_path = ":/icons/fader_knob_red.png";
lbajardsilogic@0 76 ok = m_clip.load(clip_path);
lbajardsilogic@0 77 if (ok == false) {
lbajardsilogic@0 78 std::cerr << "Error loading pixmap" << std::endl;
lbajardsilogic@0 79 }
lbajardsilogic@0 80 }
lbajardsilogic@0 81
lbajardsilogic@0 82 Fader::~Fader()
lbajardsilogic@0 83 {
lbajardsilogic@0 84
lbajardsilogic@0 85 }
lbajardsilogic@0 86
lbajardsilogic@0 87 void
lbajardsilogic@0 88 Fader::mouseMoveEvent(QMouseEvent *ev)
lbajardsilogic@0 89 {
lbajardsilogic@0 90 if (ev->button() == Qt::MidButton) {
lbajardsilogic@0 91 setValue(1.0);
lbajardsilogic@0 92 emit valueChanged(1.0);
lbajardsilogic@0 93 update();
lbajardsilogic@0 94 ev->accept();
lbajardsilogic@0 95 return;
lbajardsilogic@0 96 }
lbajardsilogic@0 97 if (!m_mousePressed) return;
lbajardsilogic@0 98
lbajardsilogic@0 99 int x = ev->x();
lbajardsilogic@0 100 int diff = x - m_mousePressX;
lbajardsilogic@0 101 if (diff == 0) return;
lbajardsilogic@0 102
lbajardsilogic@0 103 int vx = AudioLevel::multiplier_to_fader
lbajardsilogic@0 104 (m_mousePressValue, getMaxX(), AudioLevel::LongFader);
lbajardsilogic@0 105
lbajardsilogic@0 106 vx += diff;
lbajardsilogic@0 107
lbajardsilogic@0 108 if (vx > getMaxX()) vx = getMaxX();
lbajardsilogic@0 109 if (vx < 0) vx = 0;
lbajardsilogic@0 110
lbajardsilogic@0 111 float fval = AudioLevel::fader_to_multiplier
lbajardsilogic@0 112 (vx, getMaxX(), AudioLevel::LongFader);
lbajardsilogic@0 113
lbajardsilogic@0 114 setValue(fval);
lbajardsilogic@0 115 emit valueChanged(fval);
lbajardsilogic@0 116 ev->accept();
lbajardsilogic@0 117 }
lbajardsilogic@0 118
lbajardsilogic@0 119
lbajardsilogic@0 120 void
lbajardsilogic@0 121 Fader::mouseReleaseEvent(QMouseEvent *ev)
lbajardsilogic@0 122 {
lbajardsilogic@0 123 if (m_mousePressed) {
lbajardsilogic@0 124 mouseMoveEvent(ev);
lbajardsilogic@0 125 m_mousePressed = false;
lbajardsilogic@0 126 }
lbajardsilogic@0 127 }
lbajardsilogic@0 128
lbajardsilogic@0 129 void
lbajardsilogic@0 130 Fader::mouseDoubleClickEvent(QMouseEvent *)
lbajardsilogic@0 131 {
lbajardsilogic@0 132 bool ok = false;
lbajardsilogic@0 133 float min = AudioLevel::fader_to_dB
lbajardsilogic@0 134 (0, getMaxX(), AudioLevel::LongFader);
lbajardsilogic@0 135 float max = AudioLevel::fader_to_dB
lbajardsilogic@0 136 (getMaxX(), getMaxX(), AudioLevel::LongFader);
lbajardsilogic@0 137 float deft = AudioLevel::multiplier_to_dB(m_value);
lbajardsilogic@0 138
lbajardsilogic@0 139 float dB = QInputDialog::getDouble
lbajardsilogic@0 140 (this,
lbajardsilogic@0 141 tr("Enter new fader level"),
lbajardsilogic@0 142 tr("New fader level, from %1 to %2 dBFS:").arg(min).arg(max),
lbajardsilogic@0 143 deft, min, max, 3, &ok);
lbajardsilogic@0 144
lbajardsilogic@0 145 if (ok) {
lbajardsilogic@0 146 float value = AudioLevel::dB_to_multiplier(dB);
lbajardsilogic@0 147 setValue(value);
lbajardsilogic@0 148 emit valueChanged(value);
lbajardsilogic@0 149 update();
lbajardsilogic@0 150 }
lbajardsilogic@0 151 }
lbajardsilogic@0 152
lbajardsilogic@0 153 void
lbajardsilogic@0 154 Fader::mousePressEvent(QMouseEvent *ev)
lbajardsilogic@0 155 {
lbajardsilogic@0 156 if (ev->button() == Qt::MidButton ||
lbajardsilogic@0 157 ((ev->button() == Qt::LeftButton) &&
lbajardsilogic@0 158 (ev->modifiers() & Qt::ControlModifier))) {
lbajardsilogic@0 159 setValue(1.0);
lbajardsilogic@0 160 emit valueChanged(1.0);
lbajardsilogic@0 161 update();
lbajardsilogic@0 162 return;
lbajardsilogic@0 163 }
lbajardsilogic@0 164
lbajardsilogic@0 165 if (ev->button() != Qt::LeftButton) return;
lbajardsilogic@0 166 m_mousePressed = true;
lbajardsilogic@0 167 m_mousePressX = ev->x();
lbajardsilogic@0 168 m_mousePressValue = getValue();
lbajardsilogic@0 169 }
lbajardsilogic@0 170
lbajardsilogic@0 171
lbajardsilogic@0 172 void
lbajardsilogic@0 173 Fader::wheelEvent(QWheelEvent *ev)
lbajardsilogic@0 174 {
lbajardsilogic@0 175 ev->accept();
lbajardsilogic@0 176
lbajardsilogic@0 177 //!!! needs improvement
lbajardsilogic@0 178
lbajardsilogic@0 179 if (ev->delta() > 0) {
lbajardsilogic@0 180 setValue(m_value * 1.1);
lbajardsilogic@0 181 } else {
lbajardsilogic@0 182 setValue(m_value / 1.1);
lbajardsilogic@0 183 }
lbajardsilogic@0 184
lbajardsilogic@0 185 update();
lbajardsilogic@0 186 emit valueChanged(getValue());
lbajardsilogic@0 187 }
lbajardsilogic@0 188
lbajardsilogic@0 189 void
lbajardsilogic@0 190 Fader::enterEvent(QEvent *)
lbajardsilogic@0 191 {
lbajardsilogic@0 192 emit mouseEntered();
lbajardsilogic@0 193 }
lbajardsilogic@0 194
lbajardsilogic@0 195 void
lbajardsilogic@0 196 Fader::leaveEvent(QEvent *)
lbajardsilogic@0 197 {
lbajardsilogic@0 198 emit mouseLeft();
lbajardsilogic@0 199 }
lbajardsilogic@0 200
lbajardsilogic@0 201 void
lbajardsilogic@0 202 Fader::setValue(float v)
lbajardsilogic@0 203 {
lbajardsilogic@0 204 float max = AudioLevel::dB_to_multiplier(10.0);
lbajardsilogic@0 205
lbajardsilogic@0 206 if (v > max) {
lbajardsilogic@0 207 v = max;
lbajardsilogic@0 208 } else if (v < 0.0) {
lbajardsilogic@0 209 v = 0.0;
lbajardsilogic@0 210 }
lbajardsilogic@0 211
lbajardsilogic@0 212 if (m_value != v) {
lbajardsilogic@0 213 m_value = v;
lbajardsilogic@0 214 float db = AudioLevel::multiplier_to_dB(m_value);
lbajardsilogic@0 215 QString text;
lbajardsilogic@0 216 if (db <= AudioLevel::DB_FLOOR) {
lbajardsilogic@0 217 text = tr("Level: Off");
lbajardsilogic@0 218 } else {
lbajardsilogic@0 219 text = tr("Level: %1%2.%3%4 dB")
lbajardsilogic@0 220 .arg(db < 0.0 ? "-" : "")
lbajardsilogic@0 221 .arg(abs(int(db)))
lbajardsilogic@0 222 .arg(abs(int(db * 10.0) % 10))
lbajardsilogic@0 223 .arg(abs(int(db * 100.0) % 10));
lbajardsilogic@0 224 }
lbajardsilogic@0 225 std::cerr << "Fader: setting tooltip to \"" << text.toStdString() << "\"" << std::endl;
lbajardsilogic@0 226 QWidget::setToolTip(text);
lbajardsilogic@0 227 update();
lbajardsilogic@0 228 }
lbajardsilogic@0 229 }
lbajardsilogic@0 230
lbajardsilogic@0 231
lbajardsilogic@0 232 float
lbajardsilogic@0 233 Fader::getValue()
lbajardsilogic@0 234 {
lbajardsilogic@0 235 return m_value;
lbajardsilogic@0 236 }
lbajardsilogic@0 237
lbajardsilogic@0 238
lbajardsilogic@0 239
lbajardsilogic@0 240 void
lbajardsilogic@0 241 Fader::setPeakLeft(float peak)
lbajardsilogic@0 242 {
lbajardsilogic@0 243 if (this->m_peakLeft != peak) {
lbajardsilogic@0 244 this->m_peakLeft = peak;
lbajardsilogic@0 245 update();
lbajardsilogic@0 246 }
lbajardsilogic@0 247 }
lbajardsilogic@0 248
lbajardsilogic@0 249
lbajardsilogic@0 250 void
lbajardsilogic@0 251 Fader::setPeakRight(float peak)
lbajardsilogic@0 252 {
lbajardsilogic@0 253 if (this->m_peakRight != peak) {
lbajardsilogic@0 254 this->m_peakRight = peak;
lbajardsilogic@0 255 update();
lbajardsilogic@0 256 }
lbajardsilogic@0 257 }
lbajardsilogic@0 258
lbajardsilogic@0 259
lbajardsilogic@0 260 void
lbajardsilogic@0 261 Fader::paintEvent(QPaintEvent *)
lbajardsilogic@0 262 {
lbajardsilogic@0 263 QPainter painter(this);
lbajardsilogic@0 264
lbajardsilogic@0 265 // background
lbajardsilogic@0 266 painter.drawPixmap(rect(), m_back, QRect(0, 0, 116, 23));
lbajardsilogic@0 267
lbajardsilogic@0 268 int offset_L = AudioLevel::multiplier_to_fader(m_peakLeft, 116,
lbajardsilogic@0 269 AudioLevel::IEC268LongMeter);
lbajardsilogic@0 270
lbajardsilogic@0 271 painter.drawPixmap(QRect(0, 0, offset_L, 11), m_leds,
lbajardsilogic@0 272 QRect(0, 0, offset_L, 11));
lbajardsilogic@0 273
lbajardsilogic@0 274 int offset_R = AudioLevel::multiplier_to_fader(m_peakRight, 116,
lbajardsilogic@0 275 AudioLevel::IEC268LongMeter);
lbajardsilogic@0 276
lbajardsilogic@0 277 painter.drawPixmap(QRect(0, 11, offset_R, 11), m_leds,
lbajardsilogic@0 278 QRect(0, 11, offset_R, 11));
lbajardsilogic@0 279
lbajardsilogic@0 280 if (m_withoutKnob == false) {
lbajardsilogic@0 281
lbajardsilogic@0 282 static const uint knob_width = 29;
lbajardsilogic@0 283 static const uint knob_height = 9;
lbajardsilogic@0 284
lbajardsilogic@0 285 int x = AudioLevel::multiplier_to_fader(m_value, 116 - knob_width,
lbajardsilogic@0 286 AudioLevel::LongFader);
lbajardsilogic@0 287
lbajardsilogic@0 288 bool clipping = (m_peakLeft > 1.0 || m_peakRight > 1.0);
lbajardsilogic@0 289
lbajardsilogic@0 290 painter.drawPixmap(QRect(x, 7, knob_width, knob_height),
lbajardsilogic@0 291 clipping ? m_clip : m_knob,
lbajardsilogic@0 292 QRect(0, 0, knob_width, knob_height));
lbajardsilogic@0 293 }
lbajardsilogic@0 294 }
lbajardsilogic@0 295
lbajardsilogic@0 296 int
lbajardsilogic@0 297 Fader::getMaxX() const
lbajardsilogic@0 298 {
lbajardsilogic@0 299 return 116 - 12;
lbajardsilogic@0 300 }