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