changeset 1282:f90a3c2f2930

Merge from branch horizontal-scale
author Chris Cannam
date Thu, 03 May 2018 15:24:14 +0100
parents a04f1012fca2 (current diff) fc9d9f1103fa (diff)
children 6e35062fc10a
files
diffstat 16 files changed, 292 insertions(+), 58 deletions(-) [+]
line wrap: on
line diff
--- a/files.pri	Wed May 02 14:26:51 2018 +0100
+++ b/files.pri	Thu May 03 15:24:14 2018 +0100
@@ -7,6 +7,8 @@
            layer/ColourScale.h \
            layer/ColourScaleLayer.h \
            layer/FlexiNoteLayer.h \
+           layer/HorizontalFrequencyScale.h \
+           layer/HorizontalScaleProvider.h \
            layer/ImageLayer.h \
            layer/ImageRegionFinder.h \
            layer/Layer.h \
@@ -94,6 +96,7 @@
 	   layer/ColourMapper.cpp \
 	   layer/ColourScale.cpp \
            layer/FlexiNoteLayer.cpp \
+           layer/HorizontalFrequencyScale.cpp \
            layer/ImageLayer.cpp \
            layer/ImageRegionFinder.cpp \
            layer/Layer.cpp \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/layer/HorizontalFrequencyScale.cpp	Thu May 03 15:24:14 2018 +0100
@@ -0,0 +1,77 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Sonic Visualiser
+    An audio file viewer and annotation editor.
+    Centre for Digital Music, Queen Mary, University of London.
+    This file copyright 2006-2018 Chris Cannam and QMUL.
+    
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2 of the
+    License, or (at your option) any later version.  See the file
+    COPYING included with this distribution for more information.
+*/
+
+#include "HorizontalFrequencyScale.h"
+#include "HorizontalScaleProvider.h"
+#include "LayerGeometryProvider.h"
+
+#include "base/ScaleTickIntervals.h"
+
+#include <QPainter>
+
+#include <cmath>
+
+int
+HorizontalFrequencyScale::getHeight(LayerGeometryProvider *,
+                                    QPainter &paint)
+{
+    return paint.fontMetrics().height() + 10;
+}
+
+void
+HorizontalFrequencyScale::paintScale(LayerGeometryProvider *v,
+                                     const HorizontalScaleProvider *p,
+                                     QPainter &paint,
+                                     QRect r,
+                                     bool logarithmic)
+{
+    int x0 = r.x(), y0 = r.y(), x1 = r.x() + r.width(), y1 = r.y() + r.height();
+
+    paint.drawLine(x0, y0, x1, y0);
+
+    double f0 = p->getFrequencyForX(v, x0 ? x0 : 1);
+    double f1 = p->getFrequencyForX(v, x1);
+
+    int n = 20;
+
+    auto ticks =
+        logarithmic ?
+        ScaleTickIntervals::logarithmic({ f0, f1, n }) :
+        ScaleTickIntervals::linear({ f0, f1, n });
+
+    n = int(ticks.size());
+
+    int marginx = -1;
+
+    for (int i = 0; i < n; ++i) {
+        
+        double val = ticks[i].value;
+        QString label = QString::fromStdString(ticks[i].label);
+        int tw = paint.fontMetrics().width(label);
+        
+        int x = int(round(p->getXForFrequency(v, val)));
+
+        if (x < marginx) continue;
+        
+        //!!! todo: pixel scaling (here & elsewhere in these classes)
+        
+        paint.drawLine(x, y0, x, y1);
+
+        paint.drawText(x + 5, y0 + paint.fontMetrics().ascent() + 5, label);
+
+        marginx = x + tw + 10;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/layer/HorizontalFrequencyScale.h	Thu May 03 15:24:14 2018 +0100
@@ -0,0 +1,35 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Sonic Visualiser
+    An audio file viewer and annotation editor.
+    Centre for Digital Music, Queen Mary, University of London.
+    This file copyright 2006-2018 Chris Cannam and QMUL.
+    
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2 of the
+    License, or (at your option) any later version.  See the file
+    COPYING included with this distribution for more information.
+*/
+
+#ifndef SV_HORIZONTAL_FREQUENCY_SCALE_H
+#define SV_HORIZONTAL_FREQUENCY_SCALE_H
+
+#include <QRect>
+
+class QPainter;
+class LayerGeometryProvider;
+class HorizontalScaleProvider;
+
+class HorizontalFrequencyScale
+{
+public:
+    int getHeight(LayerGeometryProvider *v, QPainter &paint);
+
+    void paintScale
+    (LayerGeometryProvider *v, const HorizontalScaleProvider *provider,
+     QPainter &paint, QRect r, bool logarithmic);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/layer/HorizontalScaleProvider.h	Thu May 03 15:24:14 2018 +0100
@@ -0,0 +1,38 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Sonic Visualiser
+    An audio file viewer and annotation editor.
+    Centre for Digital Music, Queen Mary, University of London.
+    This file copyright 2006-2018 Chris Cannam and QMUL.
+    
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2 of the
+    License, or (at your option) any later version.  See the file
+    COPYING included with this distribution for more information.
+*/
+
+#ifndef SV_HORIZONTAL_SCALE_PROVIDER_H
+#define SV_HORIZONTAL_SCALE_PROVIDER_H
+
+class LayerGeometryProvider;
+
+/**
+ * Interface to be implemented by objects, such as layers or objects
+ * they delegate to, in which the X axis corresponds to frequency. For
+ * example, SpectrumLayer.
+ */
+class HorizontalScaleProvider
+{
+public:
+    virtual double getFrequencyForX(const LayerGeometryProvider *,
+                                    double x)
+        const = 0;
+    
+    virtual double getXForFrequency(const LayerGeometryProvider *,
+                                    double freq)
+        const = 0;
+};
+
+#endif
--- a/layer/LinearNumericalScale.cpp	Wed May 02 14:26:51 2018 +0100
+++ b/layer/LinearNumericalScale.cpp	Thu May 03 15:24:14 2018 +0100
@@ -4,7 +4,7 @@
     Sonic Visualiser
     An audio file viewer and annotation editor.
     Centre for Digital Music, Queen Mary, University of London.
-    This file copyright 2006-2013 Chris Cannam and QMUL.
+    This file copyright 2006-2018 Chris Cannam and QMUL.
     
     This program is free software; you can redistribute it and/or
     modify it under the terms of the GNU General Public License as
@@ -15,18 +15,17 @@
 
 #include "LinearNumericalScale.h"
 #include "VerticalScaleLayer.h"
+#include "LayerGeometryProvider.h"
 
 #include <QPainter>
 
 #include <cmath>
 
-#include "LayerGeometryProvider.h"
-
 #include "base/ScaleTickIntervals.h"
 
 int
 LinearNumericalScale::getWidth(LayerGeometryProvider *,
-                               QPainter &paint)
+                                   QPainter &paint)
 {
     return paint.fontMetrics().width("-000.00") + 10;
 }
--- a/layer/LinearNumericalScale.h	Wed May 02 14:26:51 2018 +0100
+++ b/layer/LinearNumericalScale.h	Thu May 03 15:24:14 2018 +0100
@@ -13,8 +13,8 @@
     COPYING included with this distribution for more information.
 */
 
-#ifndef LINEAR_NUMERICAL_SCALE_H
-#define LINEAR_NUMERICAL_SCALE_H
+#ifndef SV_LINEAR_NUMERICAL_SCALE_H
+#define SV_LINEAR_NUMERICAL_SCALE_H
 
 #include <QRect>
 
--- a/layer/LogNumericalScale.cpp	Wed May 02 14:26:51 2018 +0100
+++ b/layer/LogNumericalScale.cpp	Thu May 03 15:24:14 2018 +0100
@@ -4,7 +4,7 @@
     Sonic Visualiser
     An audio file viewer and annotation editor.
     Centre for Digital Music, Queen Mary, University of London.
-    This file copyright 2006-2013 Chris Cannam and QMUL.
+    This file copyright 2006-2018 Chris Cannam and QMUL.
     
     This program is free software; you can redistribute it and/or
     modify it under the terms of the GNU General Public License as
@@ -15,17 +15,15 @@
 
 #include "LogNumericalScale.h"
 #include "VerticalScaleLayer.h"
+#include "LayerGeometryProvider.h"
 
 #include "base/LogRange.h"
+#include "base/ScaleTickIntervals.h"
 
 #include <QPainter>
 
 #include <cmath>
 
-#include "LayerGeometryProvider.h"
-
-#include "base/ScaleTickIntervals.h"
-
 int
 LogNumericalScale::getWidth(LayerGeometryProvider *,
                             QPainter &paint)
@@ -80,3 +78,4 @@
         prevy = y;
     }
 }
+
--- a/layer/LogNumericalScale.h	Wed May 02 14:26:51 2018 +0100
+++ b/layer/LogNumericalScale.h	Thu May 03 15:24:14 2018 +0100
@@ -4,7 +4,7 @@
     Sonic Visualiser
     An audio file viewer and annotation editor.
     Centre for Digital Music, Queen Mary, University of London.
-    This file copyright 2006-2013 Chris Cannam and QMUL.
+    This file copyright 2006-2018 Chris Cannam and QMUL.
     
     This program is free software; you can redistribute it and/or
     modify it under the terms of the GNU General Public License as
@@ -13,8 +13,8 @@
     COPYING included with this distribution for more information.
 */
 
-#ifndef LOG_NUMERICAL_SCALE_H
-#define LOG_NUMERICAL_SCALE_H
+#ifndef SV_LOG_NUMERICAL_SCALE_H
+#define SV_LOG_NUMERICAL_SCALE_H
 
 #include <QRect>
 
@@ -28,8 +28,8 @@
     int getWidth(LayerGeometryProvider *v, QPainter &paint);
 
     void paintVertical
-    (LayerGeometryProvider *v, const VerticalScaleLayer *layer, QPainter &paint, int x0,
-     double minlog, double maxlog);
+    (LayerGeometryProvider *v, const VerticalScaleLayer *layer,
+     QPainter &paint, int x0, double minlog, double maxlog);
 };
 
 #endif
--- a/layer/PianoScale.cpp	Wed May 02 14:26:51 2018 +0100
+++ b/layer/PianoScale.cpp	Thu May 03 15:24:14 2018 +0100
@@ -22,6 +22,7 @@
 #include "base/Pitch.h"
 
 #include "LayerGeometryProvider.h"
+#include "HorizontalScaleProvider.h"
 
 #include <iostream>
 using namespace std;
--- a/layer/PianoScale.h	Wed May 02 14:26:51 2018 +0100
+++ b/layer/PianoScale.h	Thu May 03 15:24:14 2018 +0100
@@ -20,18 +20,14 @@
 
 class QPainter;
 class LayerGeometryProvider;
+class HorizontalScaleProvider;
 
 class PianoScale
 {
 public:
     void paintPianoVertical
-    (LayerGeometryProvider *v, QPainter &paint, QRect rect, double minf, double maxf);
-
-    class HorizontalScaleProvider {
-    public:
-        virtual double getFrequencyForX(const LayerGeometryProvider *, double x) const = 0;
-        virtual double getXForFrequency(const LayerGeometryProvider *, double freq) const = 0;
-    };
+    (LayerGeometryProvider *v, QPainter &paint, QRect rect,
+     double minf, double maxf);
     
     void paintPianoHorizontal
     (LayerGeometryProvider *v, const HorizontalScaleProvider *p,
--- a/layer/SliceLayer.cpp	Wed May 02 14:26:51 2018 +0100
+++ b/layer/SliceLayer.cpp	Thu May 03 15:24:14 2018 +0100
@@ -31,7 +31,7 @@
 
 SliceLayer::SliceLayer() :
     m_sliceableModel(0),
-    m_colourMap(0),
+    m_colourMap(int(ColourMapper::Ice)),
     m_energyScale(dBScale),
     m_samplingMode(SampleMean),
     m_plotStyle(PlotLines),
@@ -210,7 +210,19 @@
         break;
         
     case LogBins:
-        x = (w * log10(bin + 1)) / log10(count + 1);
+        // The 0.8 here is an awkward compromise. Our x-coord is
+        // proportional to log of bin number, with the x-coord "of a
+        // bin" being that of the left edge of the bin range. We can't
+        // start counting bins from 0, as that would give us x = -Inf
+        // and hide the first bin entirely. But if we start from 1, we
+        // are giving a lot of space to the first bin, which in most
+        // display modes won't be used because the "point" location
+        // for that bin is in the middle of it. Yet in some modes
+        // we'll still want it. A compromise is to count our first bin
+        // as "a bit less than 1", so that most of it is visible but a
+        // bit is tactfully cropped at the left edge so it doesn't
+        // take up so much space.
+        x = (w * log10(bin + 0.8)) / log10(count + 0.8);
         break;
         
     case InvertedLogBins:
@@ -247,7 +259,8 @@
         break;
         
     case LogBins:
-        bin = pow(10.0, (x * log10(count + 1)) / w) - 1.0 + eps;
+        // See comment in getXForBin
+        bin = pow(10.0, (x * log10(count + 0.8)) / w) - 0.8 + eps;
         break;
 
     case InvertedLogBins:
@@ -551,6 +564,17 @@
     }
 }
 
+bool
+SliceLayer::hasLightBackground() const
+{
+    if (usesSolidColour()) {
+        ColourMapper mapper(m_colourMap, 0, 1);
+        return mapper.hasLightBackground();
+    } else {
+        return SingleColourLayer::hasLightBackground();
+    }
+}
+
 Layer::PropertyList
 SliceLayer::getProperties() const
 {
@@ -595,7 +619,7 @@
     if (name == "Scale") return ValueProperty;
     if (name == "Sampling Mode") return ValueProperty;
     if (name == "Bin Scale") return ValueProperty;
-    if (name == "Colour" && m_plotStyle == PlotFilledBlocks) return ValueProperty;
+    if (name == "Colour" && usesSolidColour()) return ColourMapProperty;
     return SingleColourLayer::getPropertyType(name);
 }
 
@@ -653,11 +677,11 @@
         val = (m_normalize ? 1 : 0);
         *deflt = 0;
 
-    } else if (name == "Colour" && m_plotStyle == PlotFilledBlocks) {
+    } else if (name == "Colour" && usesSolidColour()) {
             
         *min = 0;
         *max = ColourMapper::getColourMapCount() - 1;
-        *deflt = 0;
+        *deflt = int(ColourMapper::Ice);
         
         val = m_colourMap;
 
@@ -703,9 +727,9 @@
 
 QString
 SliceLayer::getPropertyValueLabel(const PropertyName &name,
-                                    int value) const
+                                  int value) const
 {
-    if (name == "Colour" && m_plotStyle == PlotFilledBlocks) {
+    if (name == "Colour" && usesSolidColour()) {
         return ColourMapper::getColourMapName(value);
     }
     if (name == "Scale") {
@@ -765,7 +789,7 @@
     } else if (name == "Threshold") {
         if (value == -80) setThreshold(0.0f);
         else setThreshold(float(AudioLevel::dB_to_multiplier(value)));
-    } else if (name == "Colour" && m_plotStyle == PlotFilledBlocks) {
+    } else if (name == "Colour" && usesSolidColour()) {
         setFillColourMap(value);
     } else if (name == "Scale") {
         switch (value) {
--- a/layer/SliceLayer.h	Wed May 02 14:26:51 2018 +0100
+++ b/layer/SliceLayer.h	Thu May 03 15:24:14 2018 +0100
@@ -32,8 +32,6 @@
     SliceLayer();
     ~SliceLayer();
     
-//    virtual void setModel(const Model *model);
-//    virtual const Model *getModel() const { return m_model; }
     virtual const Model *getModel() const { return 0; }
 
     void setSliceableModel(const Model *model);    
@@ -49,6 +47,8 @@
         return ColourAndBackgroundSignificant;
     }
 
+    virtual bool hasLightBackground() const;
+
     virtual PropertyList getProperties() const;
     virtual QString getPropertyLabel(const PropertyName &) const;
     virtual QString getPropertyIconName(const PropertyName &) const;
@@ -85,6 +85,8 @@
 
     enum BinScale { LinearBins, LogBins, InvertedLogBins };
 
+    bool usesSolidColour() const { return m_plotStyle == PlotFilledBlocks; }
+    
     void setFillColourMap(int);
     int getFillColourMap() const { return m_colourMap; }
 
--- a/layer/SpectrumLayer.cpp	Wed May 02 14:26:51 2018 +0100
+++ b/layer/SpectrumLayer.cpp	Thu May 03 15:24:14 2018 +0100
@@ -25,6 +25,8 @@
 
 #include "ColourMapper.h"
 #include "PaintAssistant.h"
+#include "PianoScale.h"
+#include "HorizontalFrequencyScale.h"
 
 #include <QPainter>
 #include <QTextStream>
@@ -302,6 +304,9 @@
 {
     if (!m_sliceableModel) return 0;
     double bin = getBinForX(v, x);
+    // we assume the frequency of a bin corresponds to the centre of
+    // its visual range
+    bin -= 0.5;
     return (m_sliceableModel->getSampleRate() * bin) /
         (m_sliceableModel->getHeight() * 2);
 }
@@ -312,6 +317,8 @@
     if (!m_sliceableModel) return 0;
     double bin = (freq * m_sliceableModel->getHeight() * 2) /
         m_sliceableModel->getSampleRate();
+    // we want the centre of the bin range
+    bin += 0.5;
     return getXForBin(v, bin);
 }
 
@@ -598,25 +605,22 @@
     double thresh = (pow(10, -6) / m_gain) * (m_windowSize / 2.0); // -60dB adj
 
     int xorigin = getVerticalScaleWidth(v, false, paint) + 1;
-    int w = v->getPaintWidth() - xorigin - 1;
-
-    int pkh = int(paint.fontMetrics().height() * 0.7 + 0.5);
-    if (pkh < 10) pkh = 10;
-
-    paint.save();
+    int scaleHeight = getHorizontalScaleHeight(v, paint);
 
     if (fft && m_showPeaks) {
 
         // draw peak lines
 
-//        SVDEBUG << "Showing peaks..." << endl;
-
         int col = int(v->getCentreFrame() / fft->getResolution());
 
         paint.save();
         paint.setRenderHint(QPainter::Antialiasing, false);
-        paint.setPen(QColor(160, 160, 160)); //!!!
 
+        ColourMapper mapper =
+            hasLightBackground() ?
+            ColourMapper(ColourMapper::BlackOnWhite, 0, 1) :
+            ColourMapper(ColourMapper::WhiteOnBlack, 0, 1);
+        
         int peakminbin = 0;
         int peakmaxbin = fft->getHeight() - 1;
         double peakmaxfreq = Pitch::getFrequencyForPitch(128);
@@ -625,8 +629,6 @@
         FFTModel::PeakSet peaks = fft->getPeakFrequencies
             (FFTModel::MajorPitchAdaptivePeaks, col, peakminbin, peakmaxbin);
 
-        ColourMapper mapper(ColourMapper::BlackOnWhite, 0, 1);
-
         BiasCurve curve;
         getBiasCurve(curve);
         int cs = int(curve.size());
@@ -656,14 +658,38 @@
             (void)getYForValue(v, values[bin], norm); // don't need return value, need norm
 
             paint.setPen(mapper.map(norm));
-            paint.drawLine(x, 0, x, v->getPaintHeight() - scaleh - pkh - 1);
+            paint.drawLine(x, 0, x, v->getPaintHeight() - scaleHeight - 1);
         }
 
         paint.restore();
     }
     
+    paint.save();
+    
     SliceLayer::paint(v, paint, rect);
+    
+    paintHorizontalScale(v, paint, xorigin);
 
+    paint.restore();
+}
+
+int
+SpectrumLayer::getHorizontalScaleHeight(LayerGeometryProvider *v,
+                                        QPainter &paint) const
+{
+    int pkh = int(paint.fontMetrics().height() * 0.7 + 0.5);
+    if (pkh < 10) pkh = 10;
+
+    int scaleh = HorizontalFrequencyScale().getHeight(v, paint);
+
+    return pkh + scaleh;
+}
+
+void
+SpectrumLayer::paintHorizontalScale(LayerGeometryProvider *v,
+                                    QPainter &paint,
+                                    int xorigin) const
+{
     //!!! All of this stuff relating to depicting frequencies
     // (keyboard, crosshairs etc) should be applicable to any slice
     // layer whose model has a vertical scale unit of Hz.  However,
@@ -673,12 +699,39 @@
     // that could be relevant to Colour3DPlotLayer with unit Hz, but
     // that's a bigger proposition.
 
-    int h = v->getPaintHeight();
+    if (!v->getViewManager()->shouldShowHorizontalValueScale()) {
+        return;
+    }
+    
+    int totalScaleHeight = getHorizontalScaleHeight(v, paint); // inc piano
+    int freqScaleHeight = HorizontalFrequencyScale().getHeight(v, paint);
+    int paintHeight = v->getPaintHeight();
+    int paintWidth = v->getPaintWidth();
 
     PianoScale().paintPianoHorizontal
-        (v, this, paint, QRect(xorigin, h - pkh - 1, w + xorigin, pkh));
+        (v, this, paint,
+         QRect(xorigin, paintHeight - totalScaleHeight - 1,
+               paintWidth - 1, totalScaleHeight - freqScaleHeight));
 
-    paint.restore();
+    int scaleLeft = int(getXForBin(v, 1));
+    
+    paint.drawLine(int(getXForBin(v, 0)), paintHeight - freqScaleHeight,
+                   scaleLeft, paintHeight - freqScaleHeight);
+
+    QString hz = tr("Hz");
+    int hzw = paint.fontMetrics().width(hz);
+    if (scaleLeft > hzw + 5) {
+        paint.drawText
+            (scaleLeft - hzw - 5,
+             paintHeight - freqScaleHeight + paint.fontMetrics().ascent() + 5,
+             hz);
+    }
+
+    HorizontalFrequencyScale().paintScale
+        (v, this, paint,
+         QRect(scaleLeft, paintHeight - freqScaleHeight,
+               paintWidth, totalScaleHeight),
+         m_binScale == LogBins);
 }
 
 void
--- a/layer/SpectrumLayer.h	Wed May 02 14:26:51 2018 +0100
+++ b/layer/SpectrumLayer.h	Thu May 03 15:24:14 2018 +0100
@@ -23,7 +23,7 @@
 
 #include "data/model/DenseTimeValueModel.h"
 
-#include "PianoScale.h"
+#include "HorizontalScaleProvider.h"
 
 #include <QColor>
 #include <QMutex>
@@ -31,7 +31,7 @@
 class FFTModel;
 
 class SpectrumLayer : public SliceLayer,
-                      public PianoScale::HorizontalScaleProvider
+                      public HorizontalScaleProvider
 {
     Q_OBJECT
 
@@ -46,6 +46,9 @@
                                      std::vector<QRect> &extents) const override;
     virtual void paintCrosshairs(LayerGeometryProvider *, QPainter &, QPoint) const override;
 
+    virtual int getHorizontalScaleHeight(LayerGeometryProvider *, QPainter &) const;
+    virtual void paintHorizontalScale(LayerGeometryProvider *, QPainter &, int xorigin) const;
+    
     virtual QString getFeatureDescription(LayerGeometryProvider *v, QPoint &) const override;
 
     virtual void paint(LayerGeometryProvider *v, QPainter &paint, QRect rect) const override;
@@ -96,10 +99,10 @@
     virtual void toXml(QTextStream &stream, QString indent = "",
                        QString extraAttributes = "") const override;
 
-    virtual double getFrequencyForX(const LayerGeometryProvider *,
-                                    double x) const override;
-    virtual double getXForFrequency(const LayerGeometryProvider *,
-                                    double freq) const override;
+    virtual double getFrequencyForX(const LayerGeometryProvider *, double x)
+        const override;
+    virtual double getXForFrequency(const LayerGeometryProvider *, double freq)
+        const override;
 
 protected slots:
     void preferenceChanged(PropertyContainer::PropertyName name);
--- a/view/ViewManager.h	Wed May 02 14:26:51 2018 +0100
+++ b/view/ViewManager.h	Thu May 03 15:24:14 2018 +0100
@@ -219,6 +219,9 @@
     bool shouldShowVerticalColourScale() const {
         return m_overlayMode == AllOverlays;
     }
+    bool shouldShowHorizontalValueScale() const { // for layers where x != time
+        return m_overlayMode != NoOverlays;
+    }
     bool shouldShowSelectionExtents() const {
         return m_overlayMode != NoOverlays && m_overlayMode != GlobalOverlays;
     }
--- a/widgets/PropertyBox.cpp	Wed May 02 14:26:51 2018 +0100
+++ b/widgets/PropertyBox.cpp	Thu May 03 15:24:14 2018 +0100
@@ -251,9 +251,10 @@
     cerr << "PropertyBox[" << this
               << "(\"" << m_container->getPropertyContainerName()
               << "\")]";
-    cerr << "::updatePropertyEditor(\"" << name << "\"):";
-    cerr << " value " << value << ", have " << have << ", group \""
-              << groupName << "\"" << endl;
+    cerr << "::updatePropertyEditor(\"" << name << "\", "
+         << rangeChanged << "):";
+    cerr << " type " << type << ", value " << value
+         << ", have " << have << ", group \"" << groupName << "\"" << endl;
 #endif
 
     QString groupLabel = groupName;