diff widgets/LevelPanWidget.cpp @ 1216:dc2af6616c83

Merge from branch 3.0-integration
author Chris Cannam
date Fri, 13 Jan 2017 10:29:50 +0000
parents a68c25ba1153
children 8ef67917c301
line wrap: on
line diff
--- a/widgets/LevelPanWidget.cpp	Fri Mar 04 12:23:31 2016 +0000
+++ b/widgets/LevelPanWidget.cpp	Fri Jan 13 10:29:50 2017 +0000
@@ -21,6 +21,8 @@
 #include "layer/ColourMapper.h"
 #include "base/AudioLevel.h"
 
+#include "WidgetScale.h"
+
 #include <iostream>
 #include <cmath>
 #include <cassert>
@@ -35,9 +37,14 @@
     QWidget(parent),
     m_level(maxLevel),
     m_pan(0),
+    m_monitorLeft(-1),
+    m_monitorRight(-1),
     m_editable(true),
     m_includeMute(true)
 {
+    setToolTip(tr("Drag vertically to adjust level, horizontally to adjust pan"));
+    setLevel(1.0);
+    setPan(0.0);
 }
 
 LevelPanWidget::~LevelPanWidget()
@@ -47,22 +54,7 @@
 QSize
 LevelPanWidget::sizeHint() const
 {
-    static double ratio = 0.0;
-    if (ratio == 0.0) {
-        double baseEm;
-#ifdef Q_OS_MAC
-        baseEm = 17.0;
-#else
-        baseEm = 15.0;
-#endif
-        double em = QFontMetrics(QFont()).height();
-        ratio = em / baseEm;
-    }
-
-    int pixels = 40;
-    int scaled = int(pixels * ratio + 0.5);
-    if (pixels != 0 && scaled == 0) scaled = 1;
-    return QSize(scaled, scaled);
+    return WidgetScale::scaleQSize(QSize(40, 40));
 }
 
 static int
@@ -91,18 +83,36 @@
     else return -20.;
 }
 
+int
+LevelPanWidget::audioLevelToLevel(float audioLevel, bool withMute)
+{
+    int level;
+    if (withMute) {
+        level = AudioLevel::multiplier_to_fader
+            (audioLevel, maxLevel, AudioLevel::ShortFader);
+    } else {
+        level = db_to_level(AudioLevel::multiplier_to_dB(audioLevel));
+    }
+    if (level < 0) level = 0;
+    if (level > maxLevel) level = maxLevel;
+    return level;
+}
+
+float
+LevelPanWidget::levelToAudioLevel(int level, bool withMute)
+{
+    if (withMute) {
+        return float(AudioLevel::fader_to_multiplier
+                     (level, maxLevel, AudioLevel::ShortFader));
+    } else {
+        return float(AudioLevel::dB_to_multiplier(level_to_db(level)));
+    }
+}
+
 void
 LevelPanWidget::setLevel(float flevel)
 {
-    int level;
-    if (m_includeMute) {
-        level = AudioLevel::multiplier_to_fader
-            (flevel, maxLevel, AudioLevel::ShortFader);
-    } else {
-        level = db_to_level(AudioLevel::multiplier_to_dB(flevel));
-    }
-    if (level < 0) level = 0;
-    if (level > maxLevel) level = maxLevel;
+    int level = audioLevelToLevel(flevel, m_includeMute);
     if (level != m_level) {
 	m_level = level;
 	float convertsTo = getLevel();
@@ -116,20 +126,46 @@
 float
 LevelPanWidget::getLevel() const
 {
-    if (m_includeMute) {
-        return float(AudioLevel::fader_to_multiplier
-                     (m_level, maxLevel, AudioLevel::ShortFader));
-    } else {
-        return float(AudioLevel::dB_to_multiplier(level_to_db(m_level)));
+    float flevel = levelToAudioLevel(m_level, m_includeMute);
+    return flevel;
+}
+
+int
+LevelPanWidget::audioPanToPan(float audioPan)
+{
+    int pan = int(round(audioPan * maxPan));
+    if (pan < -maxPan) pan = -maxPan;
+    if (pan > maxPan) pan = maxPan;
+    return pan;
+}
+
+float
+LevelPanWidget::panToAudioPan(int pan)
+{
+    return float(pan) / float(maxPan);
+}
+
+void
+LevelPanWidget::setPan(float fpan)
+{
+    int pan = audioPanToPan(fpan);
+    if (pan != m_pan) {
+        m_pan = pan;
+        update();
     }
 }
 
+float
+LevelPanWidget::getPan() const
+{
+    return panToAudioPan(m_pan);
+}
+
 void
-LevelPanWidget::setPan(float pan)
+LevelPanWidget::setMonitoringLevels(float left, float right)
 {
-    m_pan = int(round(pan * maxPan));
-    if (m_pan < -maxPan) m_pan = -maxPan;
-    if (m_pan > maxPan) m_pan = maxPan;
+    m_monitorLeft = left;
+    m_monitorRight = right;
     update();
 }
 
@@ -160,23 +196,15 @@
     update();
 }
 
-float
-LevelPanWidget::getPan() const
-{
-    return float(m_pan) / float(maxPan);
-}
-
 void
 LevelPanWidget::emitLevelChanged()
 {
-    cerr << "emitting levelChanged(" << getLevel() << ")" << endl;
     emit levelChanged(getLevel());
 }
 
 void
 LevelPanWidget::emitPanChanged()
 {
-    cerr << "emitting panChanged(" << getPan() << ")" << endl;
     emit panChanged(getPan());
 }
 
@@ -338,11 +366,33 @@
     pen.setWidthF(cellLightSize(rect).width() + thin);
     pen.setCapStyle(Qt::RoundCap);
     paint.setPen(pen);
+    paint.setBrush(Qt::NoBrush);
 
     for (int pan = -maxPan; pan <= maxPan; ++pan) {
 	paint.drawLine(cellCentre(rect, 0, pan), cellCentre(rect, maxLevel, pan));
     }
 
+    if (m_monitorLeft > 0.f || m_monitorRight > 0.f) {
+        paint.setPen(Qt::NoPen);
+        for (int pan = -maxPan; pan <= maxPan; ++pan) {
+            float audioPan = panToAudioPan(pan);
+            float audioLevel;
+            if (audioPan < 0.f) {
+                audioLevel = m_monitorLeft + m_monitorRight * (1.f + audioPan);
+            } else {
+                audioLevel = m_monitorRight + m_monitorLeft * (1.f - audioPan);
+            }
+            int levelHere = audioLevelToLevel(audioLevel, false);
+            for (int level = 0; level <= levelHere; ++level) {
+                paint.setBrush(level_to_colour(level));
+                QRectF clr = cellLightRect(rect, level, pan);
+                paint.drawEllipse(clr);
+            }
+        }
+        paint.setPen(pen);
+        paint.setBrush(Qt::NoBrush);
+    }
+    
     if (isEnabled()) {
 	pen.setColor(Qt::black);
     } else {
@@ -384,5 +434,17 @@
     renderTo(this, rect(), m_editable);
 }
 
+void
+LevelPanWidget::enterEvent(QEvent *e)
+{
+    QWidget::enterEvent(e);
+    emit mouseEntered();
+}
 
+void
+LevelPanWidget::leaveEvent(QEvent *e)
+{
+    QWidget::enterEvent(e);
+    emit mouseLeft();
+}