Mercurial > hg > svgui
changeset 701:084f65094203
Extend numerical and colour scales (and piano where applicable) to note and region layers
author | Chris Cannam |
---|---|
date | Wed, 04 Dec 2013 13:39:41 +0000 |
parents | 7846175403f1 |
children | ceb9a2992d96 b81f21f2c4c3 |
files | layer/NoteLayer.cpp layer/NoteLayer.h layer/RegionLayer.cpp layer/RegionLayer.h layer/TimeValueLayer.cpp layer/TimeValueLayer.h layer/VerticalScaleLayer.h |
diffstat | 7 files changed, 186 insertions(+), 42 deletions(-) [+] |
line wrap: on
line diff
--- a/layer/NoteLayer.cpp Wed Dec 04 13:12:09 2013 +0000 +++ b/layer/NoteLayer.cpp Wed Dec 04 13:39:41 2013 +0000 @@ -23,11 +23,15 @@ #include "base/RangeMapper.h" #include "ColourDatabase.h" #include "view/View.h" + #include "PianoScale.h" +#include "LinearNumericalScale.h" +#include "LogNumericalScale.h" #include "data/model/NoteModel.h" #include "widgets/ItemEditDialog.h" +#include "widgets/TextAbbrev.h" #include <QPainter> #include <QPainterPath> @@ -105,6 +109,13 @@ return SingleColourLayer::getPropertyGroupName(name); } +QString +NoteLayer::getScaleUnits() const +{ + if (m_model) return m_model->getScaleUnits(); + else return ""; +} + int NoteLayer::getPropertyRangeAndValue(const PropertyName &name, int *min, int *max, int *deflt) const @@ -124,7 +135,7 @@ if (deflt) *deflt = 0; if (m_model) { val = UnitDatabase::getInstance()->getUnitId - (m_model->getScaleUnits()); + (getScaleUnits()); } } else { @@ -185,7 +196,7 @@ bool NoteLayer::shouldConvertMIDIToHz() const { - QString unit = m_model->getScaleUnits(); + QString unit = getScaleUnits(); return (unit != "Hz"); // if (unit == "" || // unit.startsWith("MIDI") || @@ -205,7 +216,7 @@ unit = "Hz"; min = Pitch::getFrequencyForPitch(lrintf(min)); max = Pitch::getFrequencyForPitch(lrintf(max + 1)); - } else unit = m_model->getScaleUnits(); + } else unit = getScaleUnits(); if (m_verticalScale == MIDIRangeScale || m_verticalScale == LogScale) logarithmic = true; @@ -499,7 +510,7 @@ .arg(mnote) .arg(freq); - } else if (m_model->getScaleUnits() == "Hz") { + } else if (getScaleUnits() == "Hz") { pitchText = tr("%1 Hz (%2, %3)") .arg(note.value) @@ -508,7 +519,7 @@ } else { pitchText = tr("%1 %2") - .arg(note.value).arg(m_model->getScaleUnits()); + .arg(note.value).arg(getScaleUnits()); } QString text; @@ -612,7 +623,7 @@ QString queryUnits; if (shouldConvertMIDIToHz()) queryUnits = "Hz"; - else queryUnits = m_model->getScaleUnits(); + else queryUnits = getScaleUnits(); if (shouldAutoAlign()) { @@ -793,7 +804,7 @@ paint.setPen(v->getForeground()); paint.setBrush(v->getForeground()); - QString vlabel = QString("%1%2").arg(p.value).arg(m_model->getScaleUnits()); + QString vlabel = QString("%1%2").arg(p.value).arg(getScaleUnits()); v->drawVisibleText(paint, x - paint.fontMetrics().width(vlabel) - 2, y + paint.fontMetrics().height()/2 @@ -815,28 +826,54 @@ } int -NoteLayer::getVerticalScaleWidth(View *, bool, QPainter &paint) const +NoteLayer::getVerticalScaleWidth(View *v, bool, QPainter &paint) const { if (!m_model || shouldAutoAlign()) { return 0; - } else if (m_verticalScale == LogScale || - m_verticalScale == MIDIRangeScale) { - return 10; - } else { - return 0; + } else { + if (m_verticalScale == LogScale || m_verticalScale == MIDIRangeScale) { + return LogNumericalScale().getWidth(v, paint) + 10; // for piano + } else { + return LinearNumericalScale().getWidth(v, paint); + } } } void NoteLayer::paintVerticalScale(View *v, bool, QPainter &paint, QRect) const { - if (m_verticalScale == LogScale || - m_verticalScale == MIDIRangeScale) { - float fmin, fmax; - getDisplayExtents(fmin, fmax); + if (!m_model) return; + + QString unit; + float min, max; + bool logarithmic; + + int w = getVerticalScaleWidth(v, false, paint); + int h = v->height(); + + 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(0, 0, 10, v->height()), fmin, fmax); - paint.drawLine(10, 0, 10, v->height()); + (v, paint, QRect(w - 10, 0, 10, h), + LogRange::unmap(min), + LogRange::unmap(max)); + paint.drawLine(w, 0, w, h); + } + + if (getScaleUnits() != "") { + int mw = w - 5; + paint.drawText(5, + 5 + paint.fontMetrics().ascent(), + TextAbbrev::abbreviate(getScaleUnits(), + paint.fontMetrics(), + mw)); } } @@ -1039,7 +1076,7 @@ ItemEditDialog::ShowDuration | ItemEditDialog::ShowValue | ItemEditDialog::ShowText, - m_model->getScaleUnits()); + getScaleUnits()); dialog->setFrameTime(note.frame); dialog->setValue(note.value);
--- a/layer/NoteLayer.h Wed Dec 04 13:12:09 2013 +0000 +++ b/layer/NoteLayer.h Wed Dec 04 13:39:41 2013 +0000 @@ -17,6 +17,8 @@ #define _NOTE_LAYER_H_ #include "SingleColourLayer.h" +#include "VerticalScaleLayer.h" + #include "data/model/NoteModel.h" #include <QObject> @@ -25,7 +27,8 @@ class View; class QPainter; -class NoteLayer : public SingleColourLayer +class NoteLayer : public SingleColourLayer, + public VerticalScaleLayer { Q_OBJECT @@ -128,10 +131,13 @@ void setProperties(const QXmlAttributes &attributes); + /// VerticalScaleLayer methods + virtual int getYForValue(View *v, float value) const; + virtual float getValueForY(View *v, int y) const; + virtual QString getScaleUnits() const; + protected: void getScaleExtents(View *, float &min, float &max, bool &log) const; - int getYForValue(View *v, float value) const; - float getValueForY(View *v, int y) const; bool shouldConvertMIDIToHz() const; virtual int getDefaultColourHint(bool dark, bool &impose);
--- a/layer/RegionLayer.cpp Wed Dec 04 13:12:09 2013 +0000 +++ b/layer/RegionLayer.cpp Wed Dec 04 13:39:41 2013 +0000 @@ -20,12 +20,19 @@ #include "base/Profiler.h" #include "base/LogRange.h" #include "ColourDatabase.h" + #include "ColourMapper.h" +#include "LinearNumericalScale.h" +#include "LogNumericalScale.h" +#include "LinearColourScale.h" +#include "LogColourScale.h" + #include "view/View.h" #include "data/model/RegionModel.h" #include "widgets/ItemEditDialog.h" +#include "widgets/TextAbbrev.h" #include <QPainter> #include <QPainterPath> @@ -146,7 +153,7 @@ if (deflt) *deflt = 0; if (m_model) { val = UnitDatabase::getInstance()->getUnitId - (m_model->getScaleUnits()); + (getScaleUnits()); } } else { @@ -270,7 +277,7 @@ if (!m_model) return false; min = m_model->getValueMinimum(); max = m_model->getValueMaximum(); - unit = m_model->getScaleUnits(); + unit = getScaleUnits(); if (m_verticalScale == LogScale) logarithmic = true; @@ -419,7 +426,7 @@ QString valueText; - valueText = tr("%1 %2").arg(region.value).arg(m_model->getScaleUnits()); + valueText = tr("%1 %2").arg(region.value).arg(getScaleUnits()); QString text; @@ -597,6 +604,13 @@ return found; } +QString +RegionLayer::getScaleUnits() const +{ + if (m_model) return m_model->getScaleUnits(); + else return ""; +} + void RegionLayer::getScaleExtents(View *v, float &min, float &max, bool &log) const { @@ -605,7 +619,7 @@ log = false; QString queryUnits; - queryUnits = m_model->getScaleUnits(); + queryUnits = getScaleUnits(); if (m_verticalScale == AutoAlignScale) { @@ -707,6 +721,12 @@ } float +RegionLayer::getValueForY(View *v, int y) const +{ + return getValueForY(v, y, -1); +} + +float RegionLayer::getValueForY(View *v, int y, int avoid) const { float min = 0.0, max = 0.0; @@ -947,7 +967,7 @@ paint.setPen(v->getForeground()); paint.setBrush(v->getForeground()); - QString vlabel = QString("%1%2").arg(p.value).arg(m_model->getScaleUnits()); + QString vlabel = QString("%1%2").arg(p.value).arg(getScaleUnits()); v->drawVisibleText(paint, x - paint.fontMetrics().width(vlabel) - 2, y + paint.fontMetrics().height()/2 @@ -996,7 +1016,7 @@ if (!illuminated) { QString label = p.label; if (label == "") { - label = QString("%1%2").arg(p.value).arg(m_model->getScaleUnits()); + label = QString("%1%2").arg(p.value).arg(getScaleUnits()); } int labelX, labelY; @@ -1024,6 +1044,72 @@ paint.restore(); } +int +RegionLayer::getVerticalScaleWidth(View *v, bool, QPainter &paint) const +{ + if (!m_model || + m_verticalScale == AutoAlignScale || + m_verticalScale == EqualSpaced) { + 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); + } else { + return LinearNumericalScale().getWidth(v, paint); + } + } +} + +void +RegionLayer::paintVerticalScale(View *v, bool, QPainter &paint, QRect) const +{ + if (!m_model) return; + + QString unit; + float min, max; + bool logarithmic; + + int w = getVerticalScaleWidth(v, false, paint); + int h = v->height(); + + if (m_plotStyle == PlotSegmentation) { + + 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 (getScaleUnits() != "") { + int mw = w - 5; + paint.drawText(5, + 5 + paint.fontMetrics().ascent(), + TextAbbrev::abbreviate(getScaleUnits(), + paint.fontMetrics(), + mw)); + } +} + void RegionLayer::drawStart(View *v, QMouseEvent *e) { @@ -1234,7 +1320,7 @@ ItemEditDialog::ShowDuration | ItemEditDialog::ShowValue | ItemEditDialog::ShowText, - m_model->getScaleUnits()); + getScaleUnits()); dialog->setFrameTime(region.frame); dialog->setValue(region.value);
--- a/layer/RegionLayer.h Wed Dec 04 13:12:09 2013 +0000 +++ b/layer/RegionLayer.h Wed Dec 04 13:39:41 2013 +0000 @@ -17,6 +17,9 @@ #define _REGION_LAYER_H_ #include "SingleColourLayer.h" +#include "VerticalScaleLayer.h" +#include "ColourScaleLayer.h" + #include "data/model/RegionModel.h" #include <QObject> @@ -27,7 +30,9 @@ class View; class QPainter; -class RegionLayer : public SingleColourLayer +class RegionLayer : public SingleColourLayer, + public VerticalScaleLayer, + public ColourScaleLayer { Q_OBJECT @@ -36,6 +41,9 @@ virtual void paint(View *v, QPainter &paint, QRect rect) const; + virtual int getVerticalScaleWidth(View *v, bool, QPainter &) const; + virtual void paintVerticalScale(View *v, bool, QPainter &paint, QRect rect) const; + virtual QString getFeatureDescription(View *v, QPoint &) const; virtual QString getLabelPreceding(size_t) const; @@ -116,18 +124,20 @@ virtual void toXml(QTextStream &stream, QString indent = "", QString extraAttributes = "") const; - virtual int getVerticalScaleWidth(View *, bool, QPainter &) const { return 0; } + void setProperties(const QXmlAttributes &attributes); - void setProperties(const QXmlAttributes &attributes); + /// VerticalScaleLayer and ColourScaleLayer methods + int getYForValue(View *v, float value) const; + float getValueForY(View *v, int y) const; + virtual QString getScaleUnits() const; + QColor getColourForValue(View *v, float value) const; protected slots: void recalcSpacing(); protected: + float getValueForY(View *v, int y, int avoid) const; void getScaleExtents(View *, float &min, float &max, bool &log) const; - int getYForValue(View *v, float value) const; - float getValueForY(View *v, int y, int avoid = -1) const; - QColor getColourForValue(View *v, float value) const; virtual int getDefaultColourHint(bool dark, bool &impose);
--- a/layer/TimeValueLayer.cpp Wed Dec 04 13:12:09 2013 +0000 +++ b/layer/TimeValueLayer.cpp Wed Dec 04 13:39:41 2013 +0000 @@ -28,6 +28,7 @@ #include "widgets/ItemEditDialog.h" #include "widgets/ListInputDialog.h" +#include "widgets/TextAbbrev.h" #include "ColourMapper.h" #include "PianoScale.h" @@ -1209,8 +1210,9 @@ int TimeValueLayer::getVerticalScaleWidth(View *v, bool, QPainter &paint) const { - if (!m_model || shouldAutoAlign()) return 0; - if (m_plotStyle == PlotSegmentation) { + if (!m_model || shouldAutoAlign()) { + return 0; + } else if (m_plotStyle == PlotSegmentation) { if (m_verticalScale == LogScale) { return LogColourScale().getWidth(v, paint); } else { @@ -1268,8 +1270,12 @@ } if (getScaleUnits() != "") { - paint.drawText(5, 5 + paint.fontMetrics().ascent(), - getScaleUnits()); + int mw = w - 5; + paint.drawText(5, + 5 + paint.fontMetrics().ascent(), + TextAbbrev::abbreviate(getScaleUnits(), + paint.fontMetrics(), + mw)); } }
--- a/layer/TimeValueLayer.h Wed Dec 04 13:12:09 2013 +0000 +++ b/layer/TimeValueLayer.h Wed Dec 04 13:39:41 2013 +0000 @@ -155,13 +155,13 @@ } /// VerticalScaleLayer and ColourScaleLayer methods - virtual void getScaleExtents(View *, float &min, float &max, bool &log) const; virtual int getYForValue(View *, float value) const; virtual float getValueForY(View *, int y) const; virtual QString getScaleUnits() const; virtual QColor getColourForValue(View *v, float value) const; protected: + void getScaleExtents(View *, float &min, float &max, bool &log) const; bool shouldAutoAlign() const; SparseTimeValueModel::PointList getLocalPoints(View *v, int) const;
--- a/layer/VerticalScaleLayer.h Wed Dec 04 13:12:09 2013 +0000 +++ b/layer/VerticalScaleLayer.h Wed Dec 04 13:39:41 2013 +0000 @@ -19,7 +19,6 @@ class VerticalScaleLayer { public: - virtual void getScaleExtents(View *, float &min, float &max, bool &log) const = 0; virtual int getYForValue(View *, float value) const = 0; virtual float getValueForY(View *, int y) const = 0; virtual QString getScaleUnits() const = 0;