annotate widgets/Fader.cpp @ 183:5f86ae638b04

* Omit translucent blue fill for selection rectangles that are superimposed over layers that use colours for meaningful purposes such as the spectrogram (CHARM change request)
author Chris Cannam
date Fri, 24 Nov 2006 16:56:15 +0000
parents d1e5cd4574a0
children e7cf6044c2a0
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@141 101 if (ev->button() == Qt::MidButton) {
Chris@144 102 ev->accept();
Chris@141 103 return;
Chris@141 104 }
Chris@141 105
Chris@0 106 int x = ev->x() - 6;
Chris@0 107 const int max_x = 116 - 12;
Chris@0 108
Chris@0 109 int value = x;
Chris@0 110
Chris@0 111 if (value > max_x) {
Chris@0 112 value = max_x;
Chris@0 113 } else if (value < 0) {
Chris@0 114 value = 0;
Chris@0 115 }
Chris@0 116
Chris@0 117 // float fval = float(value) / float(max_x);
Chris@0 118 float fval = AudioLevel::fader_to_multiplier
Chris@0 119 (value, max_x, AudioLevel::LongFader);
Chris@0 120
Chris@0 121 setValue(fval);
Chris@0 122 emit valueChanged(fval);
Chris@0 123
Chris@0 124 update();
Chris@0 125 }
Chris@0 126
Chris@0 127
Chris@0 128 void
Chris@132 129 Fader::mouseReleaseEvent(QMouseEvent *ev)
Chris@132 130 {
Chris@132 131 mouseMoveEvent(ev);
Chris@132 132 }
Chris@132 133
Chris@132 134
Chris@132 135 void
Chris@0 136 Fader::mouseDoubleClickEvent(QMouseEvent *)
Chris@0 137 {
Chris@0 138 setValue(1.0);
Chris@0 139 emit valueChanged(1.0);
Chris@0 140 update();
Chris@0 141 }
Chris@0 142
Chris@0 143 void
Chris@0 144 Fader::mousePressEvent(QMouseEvent *ev)
Chris@0 145 {
Chris@82 146 if (ev->button() == Qt::MidButton) {
Chris@82 147 setValue(1.0);
Chris@82 148 emit valueChanged(1.0);
Chris@82 149 update();
Chris@82 150 return;
Chris@82 151 }
Chris@82 152
Chris@0 153 int x = ev->x() - 6;
Chris@0 154 const int max_x = 116 - 12;
Chris@0 155
Chris@0 156 int value = x;
Chris@0 157
Chris@0 158 if (value > max_x) {
Chris@0 159 value = max_x;
Chris@0 160 } else if (value < 0) {
Chris@0 161 value = 0;
Chris@0 162 }
Chris@0 163
Chris@0 164 float fval = AudioLevel::fader_to_multiplier
Chris@0 165 (value, max_x, AudioLevel::LongFader);
Chris@0 166
Chris@0 167 setValue(fval);
Chris@0 168 emit valueChanged(fval);
Chris@0 169
Chris@0 170 update();
Chris@0 171 }
Chris@0 172
Chris@0 173
Chris@0 174 void
Chris@0 175 Fader::wheelEvent(QWheelEvent *ev)
Chris@0 176 {
Chris@0 177 ev->accept();
Chris@0 178
Chris@0 179 //!!! needs improvement
Chris@0 180
Chris@0 181 if (ev->delta() > 0) {
Chris@0 182 setValue(m_value * 1.1);
Chris@0 183 } else {
Chris@0 184 setValue(m_value / 1.1);
Chris@0 185 }
Chris@0 186
Chris@0 187 update();
Chris@0 188 emit valueChanged(getValue());
Chris@0 189 }
Chris@0 190
Chris@0 191
Chris@0 192 void
Chris@0 193 Fader::setValue(float v)
Chris@0 194 {
Chris@0 195 float max = AudioLevel::dB_to_multiplier(10.0);
Chris@0 196
Chris@0 197 if (v > max) {
Chris@0 198 v = max;
Chris@0 199 } else if (v < 0.0) {
Chris@0 200 v = 0.0;
Chris@0 201 }
Chris@0 202
Chris@0 203 if (m_value != v) {
Chris@0 204 m_value = v;
Chris@0 205 float db = AudioLevel::multiplier_to_dB(m_value);
Chris@0 206 if (db <= AudioLevel::DB_FLOOR) {
Chris@0 207 setToolTip(tr("Level: Off"));
Chris@0 208 } else {
Chris@0 209 setToolTip(tr("Level: %1%2.%3%4 dB")
Chris@0 210 .arg(db < 0.0 ? "-" : "")
Chris@0 211 .arg(abs(int(db)))
Chris@0 212 .arg(abs(int(db * 10.0) % 10))
Chris@0 213 .arg(abs(int(db * 100.0) % 10)));
Chris@0 214 }
Chris@0 215 update();
Chris@0 216 }
Chris@0 217 }
Chris@0 218
Chris@0 219
Chris@0 220 float
Chris@0 221 Fader::getValue()
Chris@0 222 {
Chris@0 223 return m_value;
Chris@0 224 }
Chris@0 225
Chris@0 226
Chris@0 227
Chris@0 228 void
Chris@0 229 Fader::setPeakLeft(float peak)
Chris@0 230 {
Chris@0 231 if (this->m_peakLeft != peak) {
Chris@0 232 this->m_peakLeft = peak;
Chris@0 233 update();
Chris@0 234 }
Chris@0 235 }
Chris@0 236
Chris@0 237
Chris@0 238 void
Chris@0 239 Fader::setPeakRight(float peak)
Chris@0 240 {
Chris@0 241 if (this->m_peakRight != peak) {
Chris@0 242 this->m_peakRight = peak;
Chris@0 243 update();
Chris@0 244 }
Chris@0 245 }
Chris@0 246
Chris@0 247
Chris@0 248 void
Chris@0 249 Fader::paintEvent(QPaintEvent *)
Chris@0 250 {
Chris@0 251 QPainter painter(this);
Chris@0 252
Chris@0 253 // background
Chris@0 254 painter.drawPixmap(rect(), m_back, QRect(0, 0, 116, 23));
Chris@0 255
Chris@0 256 int offset_L = AudioLevel::multiplier_to_fader(m_peakLeft, 116,
Chris@0 257 AudioLevel::IEC268LongMeter);
Chris@0 258
Chris@0 259 painter.drawPixmap(QRect(0, 0, offset_L, 11), m_leds,
Chris@0 260 QRect(0, 0, offset_L, 11));
Chris@0 261
Chris@0 262 int offset_R = AudioLevel::multiplier_to_fader(m_peakRight, 116,
Chris@0 263 AudioLevel::IEC268LongMeter);
Chris@0 264
Chris@0 265 painter.drawPixmap(QRect(0, 11, offset_R, 11), m_leds,
Chris@0 266 QRect(0, 11, offset_R, 11));
Chris@0 267
Chris@0 268 if (m_withoutKnob == false) {
Chris@0 269
Chris@0 270 static const uint knob_width = 29;
Chris@0 271 static const uint knob_height = 9;
Chris@0 272
Chris@0 273 int x = AudioLevel::multiplier_to_fader(m_value, 116 - knob_width,
Chris@0 274 AudioLevel::LongFader);
Chris@0 275
Chris@0 276 bool clipping = (m_peakLeft > 1.0 || m_peakRight > 1.0);
Chris@0 277
Chris@0 278 painter.drawPixmap(QRect(x, 7, knob_width, knob_height),
Chris@0 279 clipping ? m_clip : m_knob,
Chris@0 280 QRect(0, 0, knob_width, knob_height));
Chris@0 281 }
Chris@0 282 }
Chris@0 283
Chris@0 284