# HG changeset patch # User Chris Cannam # Date 1386164789 0 # Node ID ceb9a2992d968d545bbfcc6f4efa88a8cbf23d7d # Parent e77b1673e17e5ec7096debacff3ccf1bee9d005a# Parent 084f65094203bbbae7e22630a04cd617b149088f Merge from default branch diff -r e77b1673e17e -r ceb9a2992d96 layer/ColourScaleLayer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/layer/ColourScaleLayer.h Wed Dec 04 13:46:29 2013 +0000 @@ -0,0 +1,30 @@ +/* -*- 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-2013 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 COLOUR_SCALE_LAYER_H +#define COLOUR_SCALE_LAYER_H + +#include +#include + +class ColourScaleLayer +{ +public: + virtual QString getScaleUnits() const = 0; + virtual QColor getColourForValue(View *v, float value) const = 0; +}; + +#endif + diff -r e77b1673e17e -r ceb9a2992d96 layer/FlexiNoteLayer.cpp --- a/layer/FlexiNoteLayer.cpp Wed Dec 04 11:35:08 2013 +0000 +++ b/layer/FlexiNoteLayer.cpp Wed Dec 04 13:46:29 2013 +0000 @@ -24,11 +24,15 @@ #include "base/RangeMapper.h" #include "ColourDatabase.h" #include "view/View.h" + #include "PianoScale.h" +#include "LinearNumericalScale.h" +#include "LogNumericalScale.h" #include "data/model/FlexiNoteModel.h" #include "widgets/ItemEditDialog.h" +#include "widgets/TextAbbrev.h" #include #include @@ -116,6 +120,13 @@ return SingleColourLayer::getPropertyGroupName(name); } +QString +NoteLayer::getScaleUnits() const +{ + if (m_model) return m_model->getScaleUnits(); + else return ""; +} + int FlexiNoteLayer::getPropertyRangeAndValue(const PropertyName &name, int *min, int *max, int *deflt) const @@ -135,7 +146,7 @@ if (deflt) *deflt = 0; if (m_model) { val = UnitDatabase::getInstance()->getUnitId - (m_model->getScaleUnits()); + (getScaleUnits()); } } else { @@ -196,7 +207,7 @@ bool FlexiNoteLayer::shouldConvertMIDIToHz() const { - QString unit = m_model->getScaleUnits(); + QString unit = getScaleUnits(); return (unit != "Hz"); // if (unit == "" || // unit.startsWith("MIDI") || @@ -216,7 +227,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; @@ -543,7 +554,7 @@ .arg(mnote) .arg(freq); - } else if (m_model->getScaleUnits() == "Hz") { + } else if (getScaleUnits() == "Hz") { pitchText = tr("%1 Hz (%2, %3)") .arg(note.value) @@ -552,7 +563,7 @@ } else { pitchText = tr("%1 %2") - .arg(note.value).arg(m_model->getScaleUnits()); + .arg(note.value).arg(getScaleUnits()); } QString text; @@ -656,7 +667,7 @@ QString queryUnits; if (shouldConvertMIDIToHz()) queryUnits = "Hz"; - else queryUnits = m_model->getScaleUnits(); + else queryUnits = getScaleUnits(); if (shouldAutoAlign()) { @@ -858,30 +869,54 @@ } int -FlexiNoteLayer::getVerticalScaleWidth(View *, bool, QPainter &paint) const +FlexiNoteLayer::getVerticalScaleWidth(View *v, bool, QPainter &paint) const { - if (m_verticalScale == LinearScale || - m_verticalScale == AutoAlignScale) { + if (!m_model || shouldAutoAlign()) { return 0; - } else { - return 10; + } else { + if (m_verticalScale == LogScale || m_verticalScale == MIDIRangeScale) { + return LogNumericalScale().getWidth(v, paint) + 10; // for piano + } else { + return LinearNumericalScale().getWidth(v, paint); + } } } void FlexiNoteLayer::paintVerticalScale(View *v, bool, QPainter &paint, QRect) const { - if (m_verticalScale == LinearScale || - m_verticalScale == AutoAlignScale) { - return; + 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 { - float fmin, fmax; - bool log; - QString unit; - if (!getValueExtents(fmin, fmax, log, unit)) return; + 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)); } } @@ -1355,7 +1390,7 @@ ItemEditDialog::ShowDuration | ItemEditDialog::ShowValue | ItemEditDialog::ShowText, - m_model->getScaleUnits()); + getScaleUnits()); dialog->setFrameTime(note.frame); dialog->setValue(note.value); diff -r e77b1673e17e -r ceb9a2992d96 layer/FlexiNoteLayer.h --- a/layer/FlexiNoteLayer.h Wed Dec 04 11:35:08 2013 +0000 +++ b/layer/FlexiNoteLayer.h Wed Dec 04 13:46:29 2013 +0000 @@ -19,6 +19,8 @@ #define NOTE_HEIGHT 16 #include "SingleColourLayer.h" +#include "VerticalScaleLayer.h" + #include "data/model/FlexiNoteModel.h" #include @@ -27,7 +29,9 @@ class View; class QPainter; -class FlexiNoteLayer : public SingleColourLayer + +class FlexiNoteLayer : public SingleColourLayer, + public VerticalScaleLayer { Q_OBJECT @@ -149,10 +153,13 @@ void setVerticalRangeToNoteRange(View *v); + /// 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); diff -r e77b1673e17e -r ceb9a2992d96 layer/LinearColourScale.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/layer/LinearColourScale.cpp Wed Dec 04 13:46:29 2013 +0000 @@ -0,0 +1,97 @@ +/* -*- 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-2013 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 "LinearColourScale.h" +#include "ColourScaleLayer.h" + +#include + +#include + +#include "view/View.h" + +int +LinearColourScale::getWidth(View *v, + QPainter &paint) +{ + return paint.fontMetrics().width("-000.00") + 15; +} + +void +LinearColourScale::paintVertical(View *v, + const ColourScaleLayer *layer, + QPainter &paint, + int x0, + float min, + float max) +{ + int h = v->height(); + + int n = 10; + + float val = min; + float inc = (max - val) / n; + + char buffer[40]; + + int w = getWidth(v, paint) + x0; + + int boxx = 5, boxy = 5; + if (layer->getScaleUnits() != "") { + boxy += paint.fontMetrics().height(); + } + int boxw = 10, boxh = h - boxy - 5; + + int tx = 5 + boxx + boxw; + paint.drawRect(boxx, boxy, boxw, boxh); + + paint.save(); + for (int y = 0; y < boxh; ++y) { + float val = ((boxh - y) * (max - min)) / boxh + min; + paint.setPen(layer->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 + cerr << "inc = " << inc << ", round = " << round << ", dp = " << dp << endl; +#endif + } + + for (int i = 0; i < n; ++i) { + + int y, ty; + + y = boxy + int(boxh - ((val - min) * boxh) / (max - min)); + + ty = y - paint.fontMetrics().height() + + paint.fontMetrics().ascent() + 2; + + sprintf(buffer, "%.*f", dp, val); + QString label = QString(buffer); + + paint.drawLine(boxx + boxw - boxw/3, y, boxx + boxw, y); + paint.drawText(tx, ty, label); + + val += inc; + } +} diff -r e77b1673e17e -r ceb9a2992d96 layer/LinearColourScale.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/layer/LinearColourScale.h Wed Dec 04 13:46:29 2013 +0000 @@ -0,0 +1,36 @@ +/* -*- 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-2013 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 LINEAR_COLOUR_SCALE_H +#define LINEAR_COLOUR_SCALE_H + +#include + +class QPainter; +class View; +class ColourScaleLayer; + +class LinearColourScale +{ +public: + int getWidth(View *v, QPainter &paint); + + void paintVertical + (View *v, const ColourScaleLayer *layer, QPainter &paint, int x0, + float minf, float maxf); +}; + +#endif + diff -r e77b1673e17e -r ceb9a2992d96 layer/LinearNumericalScale.cpp --- a/layer/LinearNumericalScale.cpp Wed Dec 04 11:35:08 2013 +0000 +++ b/layer/LinearNumericalScale.cpp Wed Dec 04 13:46:29 2013 +0000 @@ -26,7 +26,7 @@ LinearNumericalScale::getWidth(View *v, QPainter &paint) { - return paint.fontMetrics().width("-000.000"); + return paint.fontMetrics().width("-000.00") + 10; } void @@ -95,7 +95,7 @@ paint.drawLine(w - 5, y, w, y); if (drawText) { - paint.drawText(w - paint.fontMetrics().width(label) - 13, + paint.drawText(w - paint.fontMetrics().width(label) - 6, ty, label); } diff -r e77b1673e17e -r ceb9a2992d96 layer/LogColourScale.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/layer/LogColourScale.cpp Wed Dec 04 13:46:29 2013 +0000 @@ -0,0 +1,99 @@ +/* -*- 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-2013 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 "LogColourScale.h" +#include "ColourScaleLayer.h" + +#include "base/LogRange.h" + +#include + +#include + +#include "view/View.h" + +int +LogColourScale::getWidth(View *v, + QPainter &paint) +{ + return paint.fontMetrics().width("-000.00") + 15; +} + +void +LogColourScale::paintVertical(View *v, + const ColourScaleLayer *layer, + QPainter &paint, + int x0, + float minlog, + float maxlog) +{ + int h = v->height(); + + int n = 10; + + float val = minlog; + float inc = (maxlog - val) / n; + + char buffer[40]; + + int w = getWidth(v, paint) + x0; + + int boxx = 5, boxy = 5; + if (layer->getScaleUnits() != "") { + boxy += paint.fontMetrics().height(); + } + int boxw = 10, boxh = h - boxy - 5; + + int tx = 5 + boxx + boxw; + paint.drawRect(boxx, boxy, boxw, boxh); + + paint.save(); + for (int y = 0; y < boxh; ++y) { + float val = ((boxh - y) * (maxlog - minlog)) / boxh + minlog; + paint.setPen(layer->getColourForValue(v, LogRange::unmap(val))); + paint.drawLine(boxx + 1, y + boxy + 1, boxx + boxw, y + boxy + 1); + } + paint.restore(); + + int dp = 0; + if (inc > 0) { + int prec = trunc(log10f(inc)); + prec -= 1; + if (prec < 0) dp = -prec; + } + + for (int i = 0; i < n; ++i) { + + int y, ty; + + y = boxy + int(boxh - ((val - minlog) * boxh) / (maxlog - minlog)); + + ty = y - paint.fontMetrics().height() + + paint.fontMetrics().ascent() + 2; + + double dv = LogRange::unmap(val); + int digits = trunc(log10f(dv)); + int sf = dp + (digits > 0 ? digits : 0); + if (sf < 2) sf = 2; + sprintf(buffer, "%.*g", sf, dv); + + QString label = QString(buffer); + + paint.drawLine(boxx + boxw - boxw/3, y, boxx + boxw, y); + paint.drawText(tx, ty, label); + + val += inc; + } +} diff -r e77b1673e17e -r ceb9a2992d96 layer/LogColourScale.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/layer/LogColourScale.h Wed Dec 04 13:46:29 2013 +0000 @@ -0,0 +1,36 @@ +/* -*- 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-2013 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 LOG_COLOUR_SCALE_H +#define LOG_COLOUR_SCALE_H + +#include + +class QPainter; +class View; +class ColourScaleLayer; + +class LogColourScale +{ +public: + int getWidth(View *v, QPainter &paint); + + void paintVertical + (View *v, const ColourScaleLayer *layer, QPainter &paint, int x0, + float minf, float maxf); +}; + +#endif + diff -r e77b1673e17e -r ceb9a2992d96 layer/LogNumericalScale.cpp --- a/layer/LogNumericalScale.cpp Wed Dec 04 11:35:08 2013 +0000 +++ b/layer/LogNumericalScale.cpp Wed Dec 04 13:46:29 2013 +0000 @@ -30,7 +30,7 @@ LogNumericalScale::getWidth(View *, QPainter &paint) { - return paint.fontMetrics().width("-000.00"); + return paint.fontMetrics().width("-000.00") + 10; } void diff -r e77b1673e17e -r ceb9a2992d96 layer/NoteLayer.cpp --- a/layer/NoteLayer.cpp Wed Dec 04 11:35:08 2013 +0000 +++ b/layer/NoteLayer.cpp Wed Dec 04 13:46:29 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 #include @@ -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,21 +826,55 @@ } int -NoteLayer::getVerticalScaleWidth(View *, bool, QPainter &paint) const +NoteLayer::getVerticalScaleWidth(View *v, bool, QPainter &paint) const { - return 10; + if (!m_model || shouldAutoAlign()) { + 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 { - float fmin, fmax; - bool log; + if (!m_model) return; + QString unit; - if (!getValueExtents(fmin, fmax, log, unit)) return; - PianoScale().paintPianoVertical - (v, paint, QRect(0, 0, 10, v->height()), fmin, fmax); - paint.drawLine(10, 0, 10, v->height()); + 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(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)); + } } void @@ -1031,7 +1076,7 @@ ItemEditDialog::ShowDuration | ItemEditDialog::ShowValue | ItemEditDialog::ShowText, - m_model->getScaleUnits()); + getScaleUnits()); dialog->setFrameTime(note.frame); dialog->setValue(note.value); diff -r e77b1673e17e -r ceb9a2992d96 layer/NoteLayer.h --- a/layer/NoteLayer.h Wed Dec 04 11:35:08 2013 +0000 +++ b/layer/NoteLayer.h Wed Dec 04 13:46:29 2013 +0000 @@ -17,6 +17,8 @@ #define _NOTE_LAYER_H_ #include "SingleColourLayer.h" +#include "VerticalScaleLayer.h" + #include "data/model/NoteModel.h" #include @@ -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); diff -r e77b1673e17e -r ceb9a2992d96 layer/RegionLayer.cpp --- a/layer/RegionLayer.cpp Wed Dec 04 11:35:08 2013 +0000 +++ b/layer/RegionLayer.cpp Wed Dec 04 13:46:29 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 #include @@ -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); diff -r e77b1673e17e -r ceb9a2992d96 layer/RegionLayer.h --- a/layer/RegionLayer.h Wed Dec 04 11:35:08 2013 +0000 +++ b/layer/RegionLayer.h Wed Dec 04 13:46:29 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 @@ -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); diff -r e77b1673e17e -r ceb9a2992d96 layer/TimeValueLayer.cpp --- a/layer/TimeValueLayer.cpp Wed Dec 04 11:35:08 2013 +0000 +++ b/layer/TimeValueLayer.cpp Wed Dec 04 13:46:29 2013 +0000 @@ -28,11 +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 #include @@ -1207,14 +1210,21 @@ int TimeValueLayer::getVerticalScaleWidth(View *v, bool, QPainter &paint) const { - int w = 0; - if (m_verticalScale == LogScale) { - w = LogNumericalScale().getWidth(v, paint); + 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 { - w = LinearNumericalScale().getWidth(v, paint); + if (m_verticalScale == LogScale) { + return LogNumericalScale().getWidth(v, paint) + 10; // for piano + } else { + return LinearNumericalScale().getWidth(v, paint); + } } - if (m_plotStyle == PlotSegmentation) return w + 20; - else return w + 10; } void @@ -1222,147 +1232,28 @@ { if (!m_model) return; -/* - int h = v->height(); - - int n = 10; - + QString unit; float min, max; bool logarithmic; - getScaleExtents(v, min, max, logarithmic); - - if (m_plotStyle == PlotSegmentation) { - QString unit; - getValueExtents(min, max, logarithmic, unit); - if (logarithmic) { - LogRange::mapRange(min, max); - } - } - - 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 (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 - cerr << "inc = " << inc << ", round = " << round << ", dp = " << dp << 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 (getScaleUnits() != "") drawText = false; - } - dispval = lrintf(val / round) * round; -#ifdef DEBUG_TIME_VALUE_LAYER - cerr << "val = " << val << ", dispval = " << dispval << 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; - } -*/ - float min, max; - bool logarithmic; - getScaleExtents(v, min, max, logarithmic); int w = getVerticalScaleWidth(v, false, paint); int h = v->height(); if (m_plotStyle == PlotSegmentation) { - //!!! todo! + 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 { @@ -1379,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)); } } diff -r e77b1673e17e -r ceb9a2992d96 layer/TimeValueLayer.h --- a/layer/TimeValueLayer.h Wed Dec 04 11:35:08 2013 +0000 +++ b/layer/TimeValueLayer.h Wed Dec 04 13:46:29 2013 +0000 @@ -18,6 +18,8 @@ #include "SingleColourLayer.h" #include "VerticalScaleLayer.h" +#include "ColourScaleLayer.h" + #include "data/model/SparseTimeValueModel.h" #include @@ -26,7 +28,9 @@ class View; class QPainter; -class TimeValueLayer : public SingleColourLayer, public VerticalScaleLayer +class TimeValueLayer : public SingleColourLayer, + public VerticalScaleLayer, + public ColourScaleLayer { Q_OBJECT @@ -150,14 +154,14 @@ } } - /// VerticalScaleLayer methods - virtual void getScaleExtents(View *, float &min, float &max, bool &log) const; + /// VerticalScaleLayer and ColourScaleLayer methods 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: - QColor getColourForValue(View *v, float value) const; + void getScaleExtents(View *, float &min, float &max, bool &log) const; bool shouldAutoAlign() const; SparseTimeValueModel::PointList getLocalPoints(View *v, int) const; diff -r e77b1673e17e -r ceb9a2992d96 layer/VerticalScaleLayer.h --- a/layer/VerticalScaleLayer.h Wed Dec 04 11:35:08 2013 +0000 +++ b/layer/VerticalScaleLayer.h Wed Dec 04 13:46:29 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; diff -r e77b1673e17e -r ceb9a2992d96 svgui.pro --- a/svgui.pro Wed Dec 04 11:35:08 2013 +0000 +++ b/svgui.pro Wed Dec 04 13:46:29 2013 +0000 @@ -30,6 +30,7 @@ HEADERS += layer/Colour3DPlotLayer.h \ layer/ColourDatabase.h \ layer/ColourMapper.h \ + layer/ColourScaleLayer.h \ layer/FlexiNoteLayer.h \ layer/ImageLayer.h \ layer/ImageRegionFinder.h \ @@ -37,6 +38,8 @@ layer/LayerFactory.h \ layer/LinearNumericalScale.h \ layer/LogNumericalScale.h \ + layer/LinearColourScale.h \ + layer/LogColourScale.h \ layer/NoteLayer.h \ layer/PaintAssistant.h \ layer/PianoScale.h \ @@ -62,6 +65,8 @@ layer/LayerFactory.cpp \ layer/LinearNumericalScale.cpp \ layer/LogNumericalScale.cpp \ + layer/LinearColourScale.cpp \ + layer/LogColourScale.cpp \ layer/NoteLayer.cpp \ layer/PaintAssistant.cpp \ layer/PianoScale.cpp \