diff layer/TimeValueLayer.cpp @ 706:97ea68f62c1f imaf_enc

Merge from default branch
author Chris Cannam
date Thu, 05 Dec 2013 09:47:02 +0000
parents 084f65094203
children ceb9a2992d96 88a16eed3338
line wrap: on
line diff
--- a/layer/TimeValueLayer.cpp	Mon Nov 04 17:12:32 2013 +0000
+++ b/layer/TimeValueLayer.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -28,8 +28,14 @@
 
 #include "widgets/ItemEditDialog.h"
 #include "widgets/ListInputDialog.h"
+#include "widgets/TextAbbrev.h"
 
 #include "ColourMapper.h"
+#include "PianoScale.h"
+#include "LinearNumericalScale.h"
+#include "LogNumericalScale.h"
+#include "LinearColourScale.h"
+#include "LogColourScale.h"
 
 #include <QPainter>
 #include <QPainterPath>
@@ -81,7 +87,7 @@
     }
 
 #ifdef DEBUG_TIME_VALUE_LAYER
-    std::cerr << "TimeValueLayer::setModel(" << model << ")" << std::endl;
+    cerr << "TimeValueLayer::setModel(" << model << ")" << endl;
 #endif
 
     emit modelReplaced();
@@ -143,6 +149,13 @@
     return SingleColourLayer::getPropertyGroupName(name);
 }
 
+QString
+TimeValueLayer::getScaleUnits() const
+{
+    if (m_model) return m_model->getScaleUnits();
+    else return "";
+}
+
 int
 TimeValueLayer::getPropertyRangeAndValue(const PropertyName &name,
 					 int *min, int *max, int *deflt) const
@@ -178,7 +191,7 @@
         if (deflt) *deflt = 0;
         if (m_model) {
             val = UnitDatabase::getInstance()->getUnitId
-                (m_model->getScaleUnits());
+                (getScaleUnits());
         }
 
     } else if (name == "Draw Segment Division Lines") {
@@ -326,7 +339,7 @@
 
     logarithmic = (m_verticalScale == LogScale);
 
-    unit = m_model->getScaleUnits();
+    unit = getScaleUnits();
 
     if (m_derivative) {
         max = std::max(fabsf(min), fabsf(max));
@@ -334,7 +347,7 @@
     }
 
 #ifdef DEBUG_TIME_VALUE_LAYER
-    std::cerr << "TimeValueLayer::getValueExtents: min = " << min << ", max = " << max << std::endl;
+    cerr << "TimeValueLayer::getValueExtents: min = " << min << ", max = " << max << endl;
 #endif
 
     if (!shouldAutoAlign() && !logarithmic && !m_derivative) {
@@ -349,7 +362,7 @@
         }
 
 #ifdef DEBUG_TIME_VALUE_LAYER
-        std::cerr << "TimeValueLayer::getValueExtents: min = " << min << ", max = " << max << " (after adjustment)" << std::endl;
+        cerr << "TimeValueLayer::getValueExtents: min = " << min << ", max = " << max << " (after adjustment)" << endl;
 #endif
     }
 
@@ -376,7 +389,7 @@
     }
 
 #ifdef DEBUG_TIME_VALUE_LAYER
-    std::cerr << "TimeValueLayer::getDisplayExtents: min = " << min << ", max = " << max << std::endl;
+    cerr << "TimeValueLayer::getDisplayExtents: min = " << min << ", max = " << max << endl;
 #endif
 
     return true;
@@ -399,7 +412,7 @@
     m_scaleMaximum = max;
 
 #ifdef DEBUG_TIME_VALUE_LAYER
-    std::cerr << "TimeValueLayer::setDisplayExtents: min = " << min << ", max = " << max << std::endl;
+    cerr << "TimeValueLayer::setDisplayExtents: min = " << min << ", max = " << max << endl;
 #endif
     
     emit layerParametersChanged();
@@ -431,7 +444,7 @@
     int nr = mapper->getPositionForValue(dmax - dmin);
 
 #ifdef DEBUG_TIME_VALUE_LAYER
-    std::cerr << "TimeValueLayer::getCurrentVerticalZoomStep: dmin = " << dmin << ", dmax = " << dmax << ", nr = " << nr << std::endl;
+    cerr << "TimeValueLayer::getCurrentVerticalZoomStep: dmin = " << dmin << ", dmax = " << dmax << ", nr = " << nr << endl;
 #endif
 
     delete mapper;
@@ -468,7 +481,7 @@
         newmin = newmax - newdist;
 
 #ifdef DEBUG_TIME_VALUE_LAYER
-        std::cerr << "newmin = " << newmin << ", newmax = " << newmax << std::endl;
+        cerr << "newmin = " << newmin << ", newmax = " << newmax << endl;
 #endif
 
     } else {
@@ -486,7 +499,7 @@
     }
     
 #ifdef DEBUG_TIME_VALUE_LAYER
-    std::cerr << "TimeValueLayer::setVerticalZoomStep: " << step << ": " << newmin << " -> " << newmax << " (range " << newdist << ")" << std::endl;
+    cerr << "TimeValueLayer::setVerticalZoomStep: " << step << ": " << newmin << " -> " << newmax << " (range " << newdist << ")" << endl;
 #endif
 
     setDisplayExtents(newmin, newmax);
@@ -594,7 +607,7 @@
     RealTime rt = RealTime::frame2RealTime(useFrame, m_model->getSampleRate());
     
     QString text;
-    QString unit = m_model->getScaleUnits();
+    QString unit = getScaleUnits();
     if (unit != "") unit = " " + unit;
 
     if (points.begin()->label == "") {
@@ -769,7 +782,7 @@
 
     if (shouldAutoAlign()) {
 
-        if (!v->getValueExtents(m_model->getScaleUnits(), min, max, log)) {
+        if (!v->getValueExtents(getScaleUnits(), min, max, log)) {
             min = m_model->getValueMinimum();
             max = m_model->getValueMaximum();
         } else if (log) {
@@ -792,7 +805,7 @@
     }
 
 #ifdef DEBUG_TIME_VALUE_LAYER
-    std::cerr << "TimeValueLayer::getScaleExtents: min = " << min << ", max = " << max << std::endl;
+    cerr << "TimeValueLayer::getScaleExtents: min = " << min << ", max = " << max << endl;
 #endif
 }
 
@@ -806,8 +819,8 @@
     getScaleExtents(v, min, max, logarithmic);
 
 #ifdef DEBUG_TIME_VALUE_LAYER
-    std::cerr << "getYForValue(" << val << "): min " << min << ", max "
-              << max << ", log " << logarithmic << std::endl;
+    cerr << "getYForValue(" << val << "): min " << min << ", max "
+              << max << ", log " << logarithmic << endl;
 #endif
 
     if (logarithmic) {
@@ -839,7 +852,7 @@
 TimeValueLayer::shouldAutoAlign() const
 {
     if (!m_model) return false;
-    QString unit = m_model->getScaleUnits();
+    QString unit = getScaleUnits();
     return (m_verticalScale == AutoAlignScale && unit != "");
 }
 
@@ -858,8 +871,8 @@
     }
 
 #ifdef DEBUG_TIME_VALUE_LAYER
-    std::cerr << "TimeValueLayer::getColourForValue: min " << min << ", max "
-              << max << ", log " << log << ", value " << val << std::endl;
+    cerr << "TimeValueLayer::getColourForValue: min " << min << ", max "
+              << max << ", log " << log << ", value " << val << endl;
 #endif
 
     QColor solid = ColourMapper(m_colourMap, min, max).map(val);
@@ -902,8 +915,8 @@
     paint.setBrush(brushColour);
 
 #ifdef DEBUG_TIME_VALUE_LAYER
-    std::cerr << "TimeValueLayer::paint: resolution is "
-	      << m_model->getResolution() << " frames" << std::endl;
+    cerr << "TimeValueLayer::paint: resolution is "
+	      << m_model->getResolution() << " frames" << endl;
 #endif
 
     float min = m_model->getValueMinimum();
@@ -920,7 +933,7 @@
 	SparseTimeValueModel::PointList localPoints =
 	    getLocalPoints(v, localPos.x());
 #ifdef DEBUG_TIME_VALUE_LAYER
-        std::cerr << "TimeValueLayer: " << localPoints.size() << " local points" << std::endl;
+        cerr << "TimeValueLayer: " << localPoints.size() << " local points" << endl;
 #endif
 	if (!localPoints.empty()) illuminateFrame = localPoints.begin()->frame;
     }
@@ -1004,8 +1017,8 @@
 	    haveNext = true;
         }
 
-//        std::cout << "frame = " << p.frame << ", x = " << x << ", haveNext = " << haveNext 
-//                  << ", nx = " << nx << std::endl;
+//        cout << "frame = " << p.frame << ", x = " << x << ", haveNext = " << haveNext 
+//                  << ", nx = " << nx << endl;
 
         if (m_plotStyle == PlotDiscreteCurves) {
             paint.setPen(QPen(getBaseQColor(), 3));
@@ -1132,7 +1145,7 @@
 	if (m_plotStyle == PlotSegmentation) {
 
 #ifdef DEBUG_TIME_VALUE_LAYER
-            std::cerr << "drawing rect" << std::endl;
+            cerr << "drawing rect" << endl;
 #endif
 	    
 	    if (nx <= x) continue;
@@ -1179,9 +1192,11 @@
         ++pointCount;
     }
 
-    if ((m_plotStyle == PlotCurve || m_plotStyle == PlotDiscreteCurves ||
-         m_plotStyle == PlotLines)
-        && !path.isEmpty()) {
+    if (m_plotStyle == PlotDiscreteCurves) {
+        paint.setRenderHint(QPainter::Antialiasing, true);
+	paint.drawPath(path);
+    } else if ((m_plotStyle == PlotCurve || m_plotStyle == PlotLines)
+               && !path.isEmpty()) {
 	paint.setRenderHint(QPainter::Antialiasing, pointCount <= v->width());
 	paint.drawPath(path);
     }
@@ -1193,11 +1208,23 @@
 }
 
 int
-TimeValueLayer::getVerticalScaleWidth(View *, bool, QPainter &paint) const
+TimeValueLayer::getVerticalScaleWidth(View *v, bool, QPainter &paint) const
 {
-    int w = paint.fontMetrics().width("-000.000");
-    if (m_plotStyle == PlotSegmentation) return w + 20;
-    else return w + 10;
+    if (!m_model || shouldAutoAlign()) {
+        return 0;
+    } else if (m_plotStyle == PlotSegmentation) {
+        if (m_verticalScale == LogScale) {
+            return LogColourScale().getWidth(v, paint);
+        } else {
+            return LinearColourScale().getWidth(v, paint);
+        }
+    } else {
+        if (m_verticalScale == LogScale) {
+            return LogNumericalScale().getWidth(v, paint) + 10; // for piano
+        } else {
+            return LinearNumericalScale().getWidth(v, paint);
+        }
+    }
 }
 
 void
@@ -1205,136 +1232,50 @@
 {
     if (!m_model) return;
 
+    QString unit;
+    float min, max;
+    bool logarithmic;
+
+    int w = getVerticalScaleWidth(v, false, paint);
     int h = v->height();
 
-    int n = 10;
+    if (m_plotStyle == PlotSegmentation) {
 
-    float min, max;
-    bool logarithmic;
-    getScaleExtents(v, min, max, logarithmic);
+        getValueExtents(min, max, logarithmic, unit);
 
-    if (m_plotStyle == PlotSegmentation) {
-        QString unit;
-        getValueExtents(min, max, logarithmic, unit);
         if (logarithmic) {
             LogRange::mapRange(min, max);
+            LogColourScale().paintVertical(v, this, paint, 0, min, max);
+        } else {
+            LinearColourScale().paintVertical(v, this, paint, 0, min, max);
+        }
+
+    } else {
+
+        getScaleExtents(v, min, max, logarithmic);
+
+        if (logarithmic) {
+            LogNumericalScale().paintVertical(v, this, paint, 0, min, max);
+        } else {
+            LinearNumericalScale().paintVertical(v, this, paint, 0, min, max);
+        }
+
+        if (logarithmic && (getScaleUnits() == "Hz")) {
+            PianoScale().paintPianoVertical
+                (v, paint, QRect(w - 10, 0, 10, h), 
+                 LogRange::unmap(min), 
+                 LogRange::unmap(max));
+            paint.drawLine(w, 0, w, h);
         }
     }
-
-    float val = min;
-    float inc = (max - val) / n;
-
-    char buffer[40];
-
-    int w = getVerticalScaleWidth(v, false, paint);
-
-    int tx = 5;
-
-    int boxx = 5, boxy = 5;
-    if (m_model->getScaleUnits() != "") {
-        boxy += paint.fontMetrics().height();
-    }
-    int boxw = 10, boxh = h - boxy - 5;
-
-    if (m_plotStyle == PlotSegmentation) {
-        tx += boxx + boxw;
-        paint.drawRect(boxx, boxy, boxw, boxh);
-    }
-
-    if (m_plotStyle == PlotSegmentation) {
-        paint.save();
-        for (int y = 0; y < boxh; ++y) {
-            float val = ((boxh - y) * (max - min)) / boxh + min;
-            if (logarithmic) {
-                paint.setPen(getColourForValue(v, LogRange::unmap(val)));
-            } else {
-                paint.setPen(getColourForValue(v, val));
-            }
-            paint.drawLine(boxx + 1, y + boxy + 1, boxx + boxw, y + boxy + 1);
-        }
-        paint.restore();
-    }
-    
-    float round = 1.f;
-    int dp = 0;
-    if (inc > 0) {
-        int prec = trunc(log10f(inc));
-        prec -= 1;
-        if (prec < 0) dp = -prec;
-        round = powf(10.f, prec);
-#ifdef DEBUG_TIME_VALUE_LAYER
-        std::cerr << "inc = " << inc << ", round = " << round << ", dp = " << dp << std::endl;
-#endif
-    }
-
-    int prevy = -1;
-                
-    for (int i = 0; i < n; ++i) {
-
-	int y, ty;
-        bool drawText = true;
-
-        float dispval = val;
-
-        if (m_plotStyle == PlotSegmentation) {
-            y = boxy + int(boxh - ((val - min) * boxh) / (max - min));
-            ty = y;
-        } else {
-            if (i == n-1 &&
-                v->height() < paint.fontMetrics().height() * (n*2)) {
-                if (m_model->getScaleUnits() != "") drawText = false;
-            }
-            dispval = lrintf(val / round) * round;
-#ifdef DEBUG_TIME_VALUE_LAYER
-            std::cerr << "val = " << val << ", dispval = " << dispval << std::endl;
-#endif
-            if (logarithmic) {
-                y = getYForValue(v, LogRange::unmap(dispval));
-            } else {
-                y = getYForValue(v, dispval);
-            }                
-            ty = y - paint.fontMetrics().height() +
-                     paint.fontMetrics().ascent() + 2;
-
-            if (prevy >= 0 && (prevy - y) < paint.fontMetrics().height()) {
-                val += inc;
-                continue;
-            }
-        }
-
-        if (logarithmic) {
-            double dv = LogRange::unmap(dispval);
-            int digits = trunc(log10f(dv));
-            int sf = dp + (digits > 0 ? digits : 0);
-            if (sf < 2) sf = 2;
-            sprintf(buffer, "%.*g", sf, dv);
-        } else {
-            sprintf(buffer, "%.*f", dp, dispval);
-        }            
-	QString label = QString(buffer);
-
-        if (m_plotStyle != PlotSegmentation) {
-            paint.drawLine(w - 5, y, w, y);
-        } else {
-            paint.drawLine(boxx + boxw - boxw/3, y, boxx + boxw, y);
-        }
-
-        if (drawText) {
-            if (m_plotStyle != PlotSegmentation) {
-                paint.drawText(tx + w - paint.fontMetrics().width(label) - 8,
-                               ty, label);
-            } else {
-                paint.drawText(tx, ty, label);
-            }
-        }
-
-        prevy = y;
-	val += inc;
-    }
-    
-    if (m_model->getScaleUnits() != "") {
-        paint.drawText(5, 5 + paint.fontMetrics().ascent(),
-                       m_model->getScaleUnits());
+        
+    if (getScaleUnits() != "") {
+        int mw = w - 5;
+        paint.drawText(5,
+                       5 + paint.fontMetrics().ascent(),
+                       TextAbbrev::abbreviate(getScaleUnits(),
+                                              paint.fontMetrics(),
+                                              mw));
     }
 }
 
@@ -1342,7 +1283,7 @@
 TimeValueLayer::drawStart(View *v, QMouseEvent *e)
 {
 #ifdef DEBUG_TIME_VALUE_LAYER
-    std::cerr << "TimeValueLayer::drawStart(" << e->x() << "," << e->y() << ")" << std::endl;
+    cerr << "TimeValueLayer::drawStart(" << e->x() << "," << e->y() << ")" << endl;
 #endif
 
     if (!m_model) return;
@@ -1362,7 +1303,7 @@
              i != points.end(); ++i) {
             if (((i->frame / resolution) * resolution) != frame) {
 #ifdef DEBUG_TIME_VALUE_LAYER
-                std::cerr << "ignoring out-of-range frame at " << i->frame << std::endl;
+                cerr << "ignoring out-of-range frame at " << i->frame << endl;
 #endif
                 continue;
             }
@@ -1392,7 +1333,7 @@
 TimeValueLayer::drawDrag(View *v, QMouseEvent *e)
 {
 #ifdef DEBUG_TIME_VALUE_LAYER
-    std::cerr << "TimeValueLayer::drawDrag(" << e->x() << "," << e->y() << ")" << std::endl;
+    cerr << "TimeValueLayer::drawDrag(" << e->x() << "," << e->y() << ")" << endl;
 #endif
 
     if (!m_model || !m_editing) return;
@@ -1407,7 +1348,7 @@
     SparseTimeValueModel::PointList points = getLocalPoints(v, e->x());
 
 #ifdef DEBUG_TIME_VALUE_LAYER
-    std::cerr << points.size() << " points" << std::endl;
+    cerr << points.size() << " points" << endl;
 #endif
 
     bool havePoint = false;
@@ -1418,18 +1359,18 @@
             if (i->frame == m_editingPoint.frame &&
                 i->value == m_editingPoint.value) {
 #ifdef DEBUG_TIME_VALUE_LAYER
-                std::cerr << "ignoring current editing point at " << i->frame << ", " << i->value << std::endl;
+                cerr << "ignoring current editing point at " << i->frame << ", " << i->value << endl;
 #endif
                 continue;
             }
             if (((i->frame / resolution) * resolution) != frame) {
 #ifdef DEBUG_TIME_VALUE_LAYER
-                std::cerr << "ignoring out-of-range frame at " << i->frame << std::endl;
+                cerr << "ignoring out-of-range frame at " << i->frame << endl;
 #endif
                 continue;
             }
 #ifdef DEBUG_TIME_VALUE_LAYER
-            std::cerr << "adjusting to new point at " << i->frame << ", " << i->value << std::endl;
+            cerr << "adjusting to new point at " << i->frame << ", " << i->value << endl;
 #endif
             m_editingPoint = *i;
             m_originalPoint = m_editingPoint;
@@ -1454,7 +1395,7 @@
 TimeValueLayer::drawEnd(View *, QMouseEvent *)
 {
 #ifdef DEBUG_TIME_VALUE_LAYER
-    std::cerr << "TimeValueLayer::drawEnd" << std::endl;
+    cerr << "TimeValueLayer::drawEnd" << endl;
 #endif
     if (!m_model || !m_editing) return;
     finish(m_editingCommand);
@@ -1511,7 +1452,7 @@
 TimeValueLayer::editStart(View *v, QMouseEvent *e)
 {
 #ifdef DEBUG_TIME_VALUE_LAYER
-    std::cerr << "TimeValueLayer::editStart(" << e->x() << "," << e->y() << ")" << std::endl;
+    cerr << "TimeValueLayer::editStart(" << e->x() << "," << e->y() << ")" << endl;
 #endif
 
     if (!m_model) return;
@@ -1534,7 +1475,7 @@
 TimeValueLayer::editDrag(View *v, QMouseEvent *e)
 {
 #ifdef DEBUG_TIME_VALUE_LAYER
-    std::cerr << "TimeValueLayer::editDrag(" << e->x() << "," << e->y() << ")" << std::endl;
+    cerr << "TimeValueLayer::editDrag(" << e->x() << "," << e->y() << ")" << endl;
 #endif
 
     if (!m_model || !m_editing) return;
@@ -1560,7 +1501,7 @@
 TimeValueLayer::editEnd(View *, QMouseEvent *)
 {
 #ifdef DEBUG_TIME_VALUE_LAYER
-    std::cerr << "TimeValueLayer::editEnd" << std::endl;
+    cerr << "TimeValueLayer::editEnd" << endl;
 #endif
     if (!m_model || !m_editing) return;
 
@@ -1601,7 +1542,7 @@
          ItemEditDialog::ShowTime |
          ItemEditDialog::ShowValue |
          ItemEditDialog::ShowText,
-         m_model->getScaleUnits());
+         getScaleUnits());
 
     dialog->setFrameTime(point.frame);
     dialog->setValue(point.value);
@@ -1900,17 +1841,17 @@
             newPoint.value = i->getValue();
         } else {
 #ifdef DEBUG_TIME_VALUE_LAYER
-            std::cerr << "Setting value on point at " << newPoint.frame << " from labeller";
+            cerr << "Setting value on point at " << newPoint.frame << " from labeller";
             if (i == points.begin()) {
-                std::cerr << ", no prev point" << std::endl;
+                cerr << ", no prev point" << endl;
             } else {
-                std::cerr << ", prev point is at " << prevPoint.frame << std::endl;
+                cerr << ", prev point is at " << prevPoint.frame << endl;
             }
 #endif
             labeller.setValue<SparseTimeValueModel::Point>
                 (newPoint, (i == points.begin()) ? 0 : &prevPoint);
 #ifdef DEBUG_TIME_VALUE_LAYER
-            std::cerr << "New point value = " << newPoint.value << std::endl;
+            cerr << "New point value = " << newPoint.value << endl;
 #endif
             if (labeller.actingOnPrevPoint() && i != points.begin()) {
                 usePrev = true;
@@ -1973,7 +1914,7 @@
     float min = attributes.value("scaleMinimum").toFloat(&ok);
     float max = attributes.value("scaleMaximum").toFloat(&alsoOk);
 #ifdef DEBUG_TIME_VALUE_LAYER
-    std::cerr << "from properties: min = " << min << ", max = " << max << std::endl;
+    cerr << "from properties: min = " << min << ", max = " << max << endl;
 #endif
     if (ok && alsoOk && min != max) setDisplayExtents(min, max);
 }