Mercurial > hg > svgui
changeset 197:6b023411087b
* Work on harmonising colour and scale ranges between types of layer
* Add normalize options to colour 3d plot layer
author | Chris Cannam |
---|---|
date | Thu, 01 Feb 2007 14:31:28 +0000 |
parents | 22c99c8aa1e0 |
children | c2ed5014d4ff |
files | layer/Colour3DPlotLayer.cpp layer/Colour3DPlotLayer.h layer/ColourMapper.cpp layer/ColourMapper.h layer/Layer.h layer/NoteLayer.cpp layer/SliceLayer.cpp layer/SliceLayer.h layer/SpectrogramLayer.cpp layer/SpectrogramLayer.h layer/TimeValueLayer.cpp layer/TimeValueLayer.h view/View.cpp view/View.h widgets/PropertyBox.cpp widgets/PropertyBox.h widgets/PropertyStack.cpp widgets/PropertyStack.h |
diffstat | 18 files changed, 666 insertions(+), 257 deletions(-) [+] |
line wrap: on
line diff
--- a/layer/Colour3DPlotLayer.cpp Wed Jan 31 12:13:47 2007 +0000 +++ b/layer/Colour3DPlotLayer.cpp Thu Feb 01 14:31:28 2007 +0000 @@ -17,6 +17,8 @@ #include "view/View.h" #include "base/Profiler.h" +#include "base/LogRange.h" +#include "ColourMapper.h" #include <QPainter> #include <QImage> @@ -32,7 +34,11 @@ Colour3DPlotLayer::Colour3DPlotLayer() : m_model(0), m_cache(0), - m_colourScale(LinearScale) + m_cacheStart(0), + m_colourScale(LinearScale), + m_colourMap(0), + m_normalizeColumns(false), + m_normalizeVisibleArea(false) { } @@ -81,26 +87,37 @@ Colour3DPlotLayer::getProperties() const { PropertyList list; + list.push_back("Colour"); list.push_back("Colour Scale"); + list.push_back("Normalize Columns"); + list.push_back("Normalize Visible Area"); return list; } QString Colour3DPlotLayer::getPropertyLabel(const PropertyName &name) const { - if (name == "Colour Scale") return tr("Colour Scale"); + if (name == "Colour") return tr("Colour"); + if (name == "Colour Scale") return tr("Scale"); + if (name == "Normalize Columns") return tr("Normalize Columns"); + if (name == "Normalize Visible Area") return tr("Normalize Visible Area"); return ""; } Layer::PropertyType Colour3DPlotLayer::getPropertyType(const PropertyName &name) const { + if (name == "Normalize Columns") return ToggleProperty; + if (name == "Normalize Visible Area") return ToggleProperty; return ValueProperty; } QString Colour3DPlotLayer::getPropertyGroupName(const PropertyName &name) const { + if (name == "Normalize Columns" || + name == "Normalize Visible Area" || + name == "Colour Scale") return tr("Scale"); return QString(); } @@ -117,10 +134,25 @@ if (name == "Colour Scale") { *min = 0; - *max = 3; + *max = 2; deft = (int)m_colourScale; + } else if (name == "Colour") { + + *min = 0; + *max = ColourMapper::getColourMapCount() - 1; + + deft = m_colourMap; + + } else if (name == "Normalize Columns") { + + deft = (m_normalizeColumns ? 1 : 0); + + } else if (name == "Normalize Visible Area") { + + deft = (m_normalizeVisibleArea ? 1 : 0); + } else { deft = Layer::getPropertyRangeAndValue(name, min, max); } @@ -132,13 +164,15 @@ Colour3DPlotLayer::getPropertyValueLabel(const PropertyName &name, int value) const { + if (name == "Colour") { + return ColourMapper::getColourMapName(value); + } if (name == "Colour Scale") { switch (value) { default: - case 0: return tr("Linear"); - case 1: return tr("Absolute"); - case 2: return tr("Meter"); - case 3: return tr("dB"); + case 0: return tr("Linear Scale"); + case 1: return tr("Log Scale"); + case 2: return tr("+/-1 Scale"); } } return tr("<unknown>"); @@ -151,10 +185,15 @@ switch (value) { default: case 0: setColourScale(LinearScale); break; - case 1: setColourScale(AbsoluteScale); break; - case 2: setColourScale(MeterScale); break; - case 3: setColourScale(dBScale); break; + case 1: setColourScale(LogScale); break; + case 2: setColourScale(PlusMinusOneScale); break; } + } else if (name == "Colour") { + setColourMap(value); + } else if (name == "Normalize Columns") { + setNormalizeColumns(value ? true : false); + } else if (name == "Normalize Visible Area") { + setNormalizeVisibleArea(value ? true : false); } } @@ -167,9 +206,49 @@ emit layerParametersChanged(); } +void +Colour3DPlotLayer::setColourMap(int map) +{ + if (m_colourMap == map) return; + m_colourMap = map; + cacheInvalid(); + emit layerParametersChanged(); +} + +void +Colour3DPlotLayer::setNormalizeColumns(bool n) +{ + if (m_normalizeColumns == n) return; + m_normalizeColumns = n; + cacheInvalid(); + emit layerParametersChanged(); +} + +bool +Colour3DPlotLayer::getNormalizeColumns() const +{ + return m_normalizeColumns; +} + +void +Colour3DPlotLayer::setNormalizeVisibleArea(bool n) +{ + if (m_normalizeVisibleArea == n) return; + m_normalizeVisibleArea = n; + cacheInvalid(); + emit layerParametersChanged(); +} + +bool +Colour3DPlotLayer::getNormalizeVisibleArea() const +{ + return m_normalizeVisibleArea; +} + bool Colour3DPlotLayer::isLayerScrollable(const View *v) const { + if (m_normalizeVisibleArea) return false; QPoint discard; return !v->shouldIlluminateLocalFeatures(this, discard); } @@ -295,6 +374,155 @@ } void +Colour3DPlotLayer::getColumn(size_t col, + DenseThreeDimensionalModel::Column &values) const +{ + m_model->getColumn(col, values); + + float colMax = 0.f; + + float min = 0.f, max = 0.f; + if (m_normalizeColumns) { + min = m_model->getMinimumLevel(); + max = m_model->getMaximumLevel(); + } + + if (m_normalizeColumns) { + for (size_t y = 0; y < values.size(); ++y) { + if (values[y] > colMax || y == 0) colMax = values[y]; + } + if (m_colourScale == LogScale) { + colMax = LogRange::map(colMax); + } + } + + for (size_t y = 0; y < values.size(); ++y) { + + float value = min; + + value = values[y]; + if (m_colourScale == LogScale) { + value = LogRange::map(value); + } + + if (m_normalizeColumns) { + if (colMax != 0) { + value = max * (value / colMax); + } else { + value = 0; + } + } + + values[y] = value; + } +} + +void +Colour3DPlotLayer::fillCache(size_t firstBin, size_t lastBin) const +{ + size_t modelStart = m_model->getStartFrame(); + size_t modelEnd = m_model->getEndFrame(); + size_t modelResolution = m_model->getResolution(); + + std::cerr << "Colour3DPlotLayer::fillCache: " << firstBin << " -> " << lastBin << std::endl; + + if (!m_normalizeVisibleArea || m_normalizeColumns) { + firstBin = modelStart / modelResolution; + lastBin = modelEnd / modelResolution; + } + + size_t cacheWidth = lastBin - firstBin + 1; + size_t cacheHeight = m_model->getHeight(); + + if (m_cache && + (m_cacheStart != firstBin || + m_cache->width() != cacheWidth || + m_cache->height() != cacheHeight)) { + + delete m_cache; + m_cache = 0; + } + + if (m_cache) return; + + m_cache = new QImage(cacheWidth, cacheHeight, QImage::Format_Indexed8); + m_cacheStart = firstBin; + + std::cerr << "Cache size " << cacheWidth << "x" << cacheHeight << " starting " << m_cacheStart << std::endl; + + m_cache->setNumColors(256); + DenseThreeDimensionalModel::Column values; + + float min = m_model->getMinimumLevel(); + float max = m_model->getMaximumLevel(); + + if (m_colourScale == LogScale) { + LogRange::mapRange(min, max); + } else if (m_colourScale == PlusMinusOneScale) { + min = -1.f; + max = 1.f; + } + + if (max == min) max = min + 1.0; + + ColourMapper mapper(m_colourMap, 0.f, 255.f); + + for (int index = 0; index < 256; ++index) { + + QColor colour = mapper.map(index); + m_cache->setColor(index, qRgb(colour.red(), colour.green(), colour.blue())); + } + + m_cache->fill(0); + + float visibleMax = 0.f; + + if (m_normalizeVisibleArea && !m_normalizeColumns) { + + for (size_t c = firstBin; c <= lastBin; ++c) { + + values.clear(); + getColumn(c, values); + + float colMax = 0.f; + + for (size_t y = 0; y < m_model->getHeight(); ++y) { + if (y >= values.size()) break; + if (y == 0 || values[y] > colMax) colMax = values[y]; + } + + if (c == firstBin || colMax > visibleMax) visibleMax = colMax; + } + } + + for (size_t c = firstBin; c <= lastBin; ++c) { + + values.clear(); + getColumn(c, values); + + for (size_t y = 0; y < m_model->getHeight(); ++y) { + + float value = min; + if (y < values.size()) { + value = values[y]; + } + + if (m_normalizeVisibleArea && !m_normalizeColumns) { + if (visibleMax != 0) { + value = max * (value / visibleMax); + } + } + + int pixel = int(((value - min) * 256) / (max - min)); + if (pixel < 0) pixel = 0; + if (pixel > 255) pixel = 255; + + m_cache->setPixel(c - firstBin, y, pixel); + } + } +} + +void Colour3DPlotLayer::paint(View *v, QPainter &paint, QRect rect) const { // Profiler profiler("Colour3DPlotLayer::paint"); @@ -311,96 +539,39 @@ return; } + if (m_normalizeVisibleArea && !m_normalizeColumns) rect = v->rect(); + size_t modelStart = m_model->getStartFrame(); size_t modelEnd = m_model->getEndFrame(); size_t modelResolution = m_model->getResolution(); - size_t cacheWidth = (modelEnd - modelStart) / modelResolution + 1; - size_t cacheHeight = m_model->getHeight(); + // The cache is from the model's start frame to the model's end + // frame at the model's window increment frames per pixel. We + // want to draw from our start frame + x0 * zoomLevel to our start + // frame + x1 * zoomLevel at zoomLevel frames per pixel. - if (m_cache && - (m_cache->width() != cacheWidth || - m_cache->height() != cacheHeight)) { + // We have quite different paint mechanisms for rendering "large" + // bins (more than one bin per pixel in both directions) and + // "small". This is "large"; see paintDense below for "small". - delete m_cache; - m_cache = 0; - } + int x0 = rect.left(); + int x1 = rect.right() + 1; - if (!m_cache) { + int h = v->height(); - m_cache = new QImage(cacheWidth, cacheHeight, QImage::Format_Indexed8); + float srRatio = + float(v->getViewManager()->getMainModelSampleRate()) / + float(m_model->getSampleRate()); - std::cerr << "Cache size " << cacheWidth << "x" << cacheHeight << std::endl; + int sx0 = int((v->getFrameForX(x0) / srRatio - long(modelStart)) + / long(modelResolution)); + int sx1 = int((v->getFrameForX(x1) / srRatio - long(modelStart)) + / long(modelResolution)); + int sh = m_model->getHeight(); - m_cache->setNumColors(256); - DenseThreeDimensionalModel::Column values; - - float min = m_model->getMinimumLevel(); - float max = m_model->getMaximumLevel(); - - if (max == min) max = min + 1.0; - - int zeroIndex = 0; - if (min < 0.f) { - if (m_colourScale == LinearScale) { - zeroIndex = int(((-min) * 256) / (max - min)); - } else { - max = std::max(-min, max); - min = 0; - } - } - if (zeroIndex < 0) zeroIndex = 0; - if (zeroIndex > 255) zeroIndex = 255; - - //!!! want this and spectrogram to share a colour mapping unit - - for (int index = 0; index < 256; ++index) { - int effective = abs(((index - zeroIndex) * 255) / - std::max(255 - zeroIndex, zeroIndex)); - int hue = 256 - effective; - if (zeroIndex > 0) { - if (index <= zeroIndex) hue = 255; - else hue = 0; - } - while (hue < 0) hue += 255; - while (hue > 255) hue -= 255; - int saturation = effective / 2 + 128; - if (saturation < 0) saturation = -saturation; - if (saturation > 255) saturation = 255; - int value = effective; - if (value < 0) value = -value; - if (value > 255) value = 255; -// std::cerr << "min: " << min << ", max: " << max << ", zi " << zeroIndex << ", index " << index << ": " << hue << ", " << saturation << ", " << value << std::endl; - QColor colour = QColor::fromHsv(hue, saturation, value); -// std::cerr << "rgb: " << colour.red() << "," << colour.green() << "," << colour.blue() << std::endl; - m_cache->setColor(index, qRgb(colour.red(), colour.green(), colour.blue())); - } - - m_cache->fill(zeroIndex); - - for (size_t f = modelStart; f <= modelEnd; f += modelResolution) { - - values.clear(); - m_model->getColumn(f / modelResolution, values); - - for (size_t y = 0; y < m_model->getHeight(); ++y) { - - float value = min; - if (y < values.size()) { - value = values[y]; - if (m_colourScale != LinearScale) { - value = fabs(value); - } - } - - int pixel = int(((value - min) * 256) / (max - min)); - if (pixel < 0) pixel = 0; - if (pixel > 255) pixel = 255; - - m_cache->setPixel(f / modelResolution, y, pixel); - } - } - } + if (sx0 > 0) --sx0; + fillCache(sx0 < 0 ? 0 : sx0, + sx1 < 0 ? 0 : sx1); if (m_model->getHeight() >= v->height() || modelResolution < v->getZoomLevel() / 2) { @@ -408,29 +579,6 @@ return; } - int x0 = rect.left(); - int x1 = rect.right() + 1; - - int h = v->height(); - - // The cache is from the model's start frame to the model's end - // frame at the model's window increment frames per pixel. We - // want to draw from our start frame + x0 * zoomLevel to our start - // frame + x1 * zoomLevel at zoomLevel frames per pixel. - - //!!! Strictly speaking we want quite different paint mechanisms - //for models that have more than one bin per pixel in either - //direction. This one is only really appropriate for models with - //far fewer bins in both directions. - - float srRatio = - float(v->getViewManager()->getMainModelSampleRate()) / - float(m_model->getSampleRate()); - - int sx0 = int((v->getFrameForX(x0) / srRatio - long(modelStart)) / long(modelResolution)); - int sx1 = int((v->getFrameForX(x1) / srRatio - long(modelStart)) / long(modelResolution)); - int sh = m_model->getHeight(); - #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT std::cerr << "Colour3DPlotLayer::paint: w " << w << ", h " << h << ", sx0 " << sx0 << ", sx1 " << sx1 << ", sw " << sw << ", sh " << sh << std::endl; std::cerr << "Colour3DPlotLayer: sample rate is " << m_model->getSampleRate() << ", resolution " << m_model->getResolution() << std::endl; @@ -440,8 +588,11 @@ bool illuminate = v->shouldIlluminateLocalFeatures(this, illuminatePos); char labelbuf[10]; - for (int sx = sx0 - 1; sx <= sx1; ++sx) { + for (int sx = sx0; sx <= sx1; ++sx) { + int scx = 0; + if (sx > m_cacheStart) scx = sx - m_cacheStart; + int fx = sx * int(modelResolution); if (fx + modelResolution < int(modelStart) || @@ -461,9 +612,9 @@ int ry0 = h - (sy * h) / sh - 1; QRgb pixel = qRgb(255, 255, 255); - if (sx >= 0 && sx < m_cache->width() && + if (scx >= 0 && scx < m_cache->width() && sy >= 0 && sy < m_cache->height()) { - pixel = m_cache->pixel(sx, sy); + pixel = m_cache->pixel(scx, sy); } QRect r(rx0, ry0 - h / sh - 1, rw, h / sh + 1); @@ -499,9 +650,9 @@ paint.drawRect(r); if (showLabel) { - if (sx >= 0 && sx < m_cache->width() && + if (scx >= 0 && scx < m_cache->width() && sy >= 0 && sy < m_cache->height()) { - float value = m_model->getValueAt(sx, sy); + float value = m_model->getValueAt(scx, sy); sprintf(labelbuf, "%06f", value); QString text(labelbuf); paint.setPen(Qt::white); @@ -566,7 +717,10 @@ for (int sx = sx0i; sx <= sx1i; ++sx) { - if (sx < 0 || sx >= m_cache->width()) continue; + int scx = 0; + if (sx > m_cacheStart) scx = sx - m_cacheStart; + + if (scx < 0 || scx >= m_cache->width()) continue; for (int sy = sy0i; sy <= sy1i; ++sy) { @@ -578,8 +732,8 @@ if (sy == sy0i) prop *= (sy + 1) - sy0; if (sy == sy1i) prop *= sy1 - sy; - mag += prop * m_cache->pixelIndex(sx, sy); - max = std::max(max, m_cache->pixelIndex(sx, sy)); + mag += prop * m_cache->pixelIndex(scx, sy); + max = std::max(max, m_cache->pixelIndex(scx, sy)); div += prop; } } @@ -624,6 +778,43 @@ return true; } +QString +Colour3DPlotLayer::toXmlString(QString indent, QString extraAttributes) const +{ + QString s; + + s += QString("scale=\"%1\" " + "colourScheme=\"%2\" " + "normalizeColumns=\"%3\" " + "normalizeVisibleArea=\"%4\"") + .arg((int)m_colourScale) + .arg(m_colourMap) + .arg(m_normalizeColumns ? "true" : "false") + .arg(m_normalizeVisibleArea ? "true" : "false"); + + return Layer::toXmlString(indent, extraAttributes + " " + s); +} + +void +Colour3DPlotLayer::setProperties(const QXmlAttributes &attributes) +{ + bool ok = false; + + ColourScale scale = (ColourScale)attributes.value("scale").toInt(&ok); + if (ok) setColourScale(scale); + + int colourMap = attributes.value("colourScheme").toInt(&ok); + if (ok) setColourMap(colourMap); + + bool normalizeColumns = + (attributes.value("normalizeColumns").trimmed() == "true"); + setNormalizeColumns(normalizeColumns); + + bool normalizeVisibleArea = + (attributes.value("normalizeVisibleArea").trimmed() == "true"); + setNormalizeVisibleArea(normalizeVisibleArea); +} + #ifdef INCLUDE_MOCFILES #include "Colour3DPlotLayer.moc.cpp" #endif
--- a/layer/Colour3DPlotLayer.h Wed Jan 31 12:13:47 2007 +0000 +++ b/layer/Colour3DPlotLayer.h Thu Feb 01 14:31:28 2007 +0000 @@ -79,17 +79,27 @@ virtual QString getPropertyValueLabel(const PropertyName &, int value) const; virtual void setProperty(const PropertyName &, int value); - - void setProperties(const QXmlAttributes &) { } + virtual void setProperties(const QXmlAttributes &); - //!!! harmonize with spectrogram - enum ColourScale { LinearScale, AbsoluteScale, MeterScale, dBScale }; + enum ColourScale { LinearScale, LogScale, PlusMinusOneScale }; void setColourScale(ColourScale); ColourScale getColourScale() const { return m_colourScale; } + void setColourMap(int map); + int getColourMap() const; + + void setNormalizeColumns(bool n); + bool getNormalizeColumns() const; + + void setNormalizeVisibleArea(bool n); + bool getNormalizeVisibleArea() const; + virtual const Model *getSliceableModel() const { return m_model; } + virtual QString toXmlString(QString indent = "", + QString extraAttributes = "") const; + protected slots: void cacheInvalid(); void cacheInvalid(size_t startFrame, size_t endFrame); @@ -98,10 +108,17 @@ const DenseThreeDimensionalModel *m_model; // I do not own this mutable QImage *m_cache; + mutable size_t m_cacheStart; ColourScale m_colourScale; + int m_colourMap; + bool m_normalizeColumns; + bool m_normalizeVisibleArea; + + void getColumn(size_t col, DenseThreeDimensionalModel::Column &) const; virtual int getColourScaleWidth(QPainter &) const; + virtual void fillCache(size_t firstBin, size_t lastBin) const; virtual void paintDense(View *v, QPainter &paint, QRect rect) const; };
--- a/layer/ColourMapper.cpp Wed Jan 31 12:13:47 2007 +0000 +++ b/layer/ColourMapper.cpp Thu Feb 01 14:31:28 2007 +0000 @@ -15,12 +15,19 @@ #include "ColourMapper.h" +#include <iostream> + ColourMapper::ColourMapper(int map, float min, float max) : QObject(), m_map(map), m_min(min), m_max(max) { + if (m_min == m_max) { + std::cerr << "WARNING: ColourMapper: min == max (== " << m_min + << "), adjusting" << std::endl; + m_max = m_min + 1; + } } ColourMapper::~ColourMapper() @@ -30,13 +37,13 @@ int ColourMapper::getColourMapCount() { - return 8; + return 10; } QString ColourMapper::getColourMapName(int n) { - if (n >= 8) return tr("<unknown>"); + if (n >= getColourMapCount()) return tr("<unknown>"); StandardMap map = (StandardMap)n; switch (map) { @@ -48,6 +55,8 @@ case BlueOnBlack: return tr("Blue on Black"); case Sunset: return tr("Sunset"); case FruitSalad: return tr("Fruit Salad"); + case Banded: return tr("Banded"); + case Highlight: return tr("Highlight"); } return tr("<unknown>"); @@ -65,7 +74,7 @@ float red = 0.f, green = 0.3333f, blue = 0.6666f, pieslice = 0.3333f; - if (m_map >= 8) return Qt::black; + if (m_map >= getColourMapCount()) return Qt::black; StandardMap map = (StandardMap)m_map; switch (map) { @@ -99,12 +108,14 @@ break; case BlueOnBlack: - h = blue / 1.f; + h = blue; s = 1.f; v = norm * 2.f; - if (v > 1) { + if (v > 1.f) { v = 1.f; - s = 1.f - (sqrtf(norm) - 0.707f) * 3.414f; + s = 1.f - (sqrtf(norm) - 0.707f) * 3.413f; + if (s < 0.f) s = 0.f; + if (s > 1.f) s = 1.f; } break; @@ -123,11 +134,26 @@ break; case FruitSalad: - h = blue + (pieslice/2.f) - norm; + h = blue + (pieslice/6.f) - norm; if (h < 0.f) h += 1.f; s = 1.f; v = 1.f; break; + + case Banded: + if (norm < 0.125) return Qt::darkGreen; + else if (norm < 0.25) return Qt::green; + else if (norm < 0.375) return Qt::darkBlue; + else if (norm < 0.5) return Qt::blue; + else if (norm < 0.625) return Qt::darkYellow; + else if (norm < 0.75) return Qt::yellow; + else if (norm < 0.875) return Qt::darkRed; + else return Qt::red; + break; + + case Highlight: + if (norm > 0.99) return Qt::white; + else return Qt::darkBlue; } if (hsv) { @@ -140,7 +166,7 @@ QColor ColourMapper::getContrastingColour() const { - if (m_map >= 8) return Qt::white; + if (m_map >= getColourMapCount()) return Qt::white; StandardMap map = (StandardMap)m_map; switch (map) { @@ -168,6 +194,12 @@ case FruitSalad: return Qt::white; + + case Banded: + return Qt::cyan; + + case Highlight: + return Qt::red; } return Qt::white;
--- a/layer/ColourMapper.h Wed Jan 31 12:13:47 2007 +0000 +++ b/layer/ColourMapper.h Thu Feb 01 14:31:28 2007 +0000 @@ -38,7 +38,9 @@ RedOnBlue, YellowOnBlack, BlueOnBlack, - FruitSalad + FruitSalad, + Banded, + Highlight }; int getMap() const { return m_map; }
--- a/layer/Layer.h Wed Jan 31 12:13:47 2007 +0000 +++ b/layer/Layer.h Thu Feb 01 14:31:28 2007 +0000 @@ -357,6 +357,7 @@ void modelReplaced(); void layerParametersChanged(); + void layerParameterRangesChanged(); void layerNameChanged(); void verticalZoomChanged();
--- a/layer/NoteLayer.cpp Wed Jan 31 12:13:47 2007 +0000 +++ b/layer/NoteLayer.cpp Thu Feb 01 14:31:28 2007 +0000 @@ -19,6 +19,7 @@ #include "base/RealTime.h" #include "base/Profiler.h" #include "base/Pitch.h" +#include "base/LogRange.h" #include "view/View.h" #include "data/model/NoteModel.h" @@ -485,8 +486,7 @@ } else if (log) { - min = (min < 0.0) ? -log10(-min) : (min == 0.0) ? 0.0 : log10(min); - max = (max < 0.0) ? -log10(-max) : (max == 0.0) ? 0.0 : log10(max); + LogRange::mapRange(min, max); std::cerr << "NoteLayer[" << this << "]::getScaleExtents: min = " << min << ", max = " << max << ", log = " << log << std::endl; @@ -506,8 +506,7 @@ } if (m_verticalScale == LogScale || m_verticalScale == MIDIRangeScale) { - min = (min < 0.0) ? -log10(-min) : (min == 0.0) ? 0.0 : log10(min); - max = (max < 0.0) ? -log10(-max) : (max == 0.0) ? 0.0 : log10(max); + LogRange::mapRange(min, max); log = true; } } @@ -533,7 +532,7 @@ } if (logarithmic) { - val = (val < 0.0) ? -log10(-val) : (val == 0.0) ? 0.0 : log10(val); + val = LogRange::map(val); // std::cerr << "logarithmic true, val now = " << val << std::endl; } @@ -554,7 +553,7 @@ float val = min + (float(h - y) * float(max - min)) / h; if (logarithmic) { - val = pow(10, val); + val = powf(10.f, val); } if (shouldConvertMIDIToHz()) {
--- a/layer/SliceLayer.cpp Wed Jan 31 12:13:47 2007 +0000 +++ b/layer/SliceLayer.cpp Thu Feb 01 14:31:28 2007 +0000 @@ -21,6 +21,7 @@ #include "base/RangeMapper.h" #include "base/RealTime.h" +#include "ColourMapper.h" #include "PaintAssistant.h" #include <QPainter> @@ -29,6 +30,7 @@ SliceLayer::SliceLayer() : m_sliceableModel(0), m_colour(Qt::darkBlue), + m_colourMap(0), m_energyScale(dBScale), m_samplingMode(SamplePeak), m_plotStyle(PlotSteps), @@ -175,6 +177,8 @@ float py = 0; float nx = xorigin; + ColourMapper mapper(m_colourMap, 0, 1); + for (size_t bin = 0; bin < mh; ++bin) { float x; @@ -202,6 +206,7 @@ float value = values[bin]; value *= m_gain; + float norm = 0.f; float y = 0.f; switch (m_energyScale) { @@ -211,16 +216,19 @@ float db = thresh; if (value > 0.f) db = 10.f * log10f(value); if (db < thresh) db = thresh; - float val = (db - thresh) / -thresh; - y = yorigin - (float(h) * val); + norm = (db - thresh) / -thresh; + y = yorigin - (float(h) * norm); break; } case MeterScale: - y = yorigin - AudioLevel::multiplier_to_preview(value, h); + y = AudioLevel::multiplier_to_preview(value, h); + norm = float(y) / float(h); + y = yorigin - y; break; default: + norm = value; y = yorigin - (float(h) * value); break; } @@ -249,15 +257,24 @@ path.lineTo(nx, y); path.lineTo(nx, yorigin); path.lineTo(x, yorigin); + + } else if (m_plotStyle == PlotFilledBlocks) { + + paint.fillRect(QRectF(x, y, nx - x, yorigin - y), mapper.map(norm)); } py = y; } - paint.drawPath(path); + if (m_plotStyle != PlotFilledBlocks) { + paint.drawPath(path); + } paint.restore(); - if (v->getViewManager() && v->getViewManager()->shouldShowFrameCount()) { + QPoint discard; + + if (v->getViewManager() && v->getViewManager()->shouldShowFrameCount() && + v->shouldIlluminateLocalFeatures(this, discard)) { int sampleRate = m_sliceableModel->getSampleRate(); @@ -435,15 +452,25 @@ } else if (name == "Colour") { - *min = 0; - *max = 5; + if (m_plotStyle == PlotFilledBlocks) { + + *min = 0; + *max = ColourMapper::getColourMapCount() - 1; - if (m_colour == Qt::black) deft = 0; - else if (m_colour == Qt::darkRed) deft = 1; - else if (m_colour == Qt::darkBlue) deft = 2; - else if (m_colour == Qt::darkGreen) deft = 3; - else if (m_colour == QColor(200, 50, 255)) deft = 4; - else if (m_colour == QColor(255, 150, 50)) deft = 5; + deft = m_colourMap; + + } else { + + *min = 0; + *max = 5; + + if (m_colour == Qt::black) deft = 0; + else if (m_colour == Qt::darkRed) deft = 1; + else if (m_colour == Qt::darkBlue) deft = 2; + else if (m_colour == Qt::darkGreen) deft = 3; + else if (m_colour == QColor(200, 50, 255)) deft = 4; + else if (m_colour == QColor(255, 150, 50)) deft = 5; + } } else if (name == "Scale") { @@ -462,14 +489,15 @@ } else if (name == "Plot Type") { *min = 0; - *max = 2; + *max = 3; deft = (int)m_plotStyle; } else if (name == "Bin Scale") { *min = 0; - *max = 2; +// *max = 2; + *max = 1; // I don't think we really do want to offer inverted log deft = (int)m_binScale; @@ -485,14 +513,18 @@ int value) const { if (name == "Colour") { - switch (value) { - default: - case 0: return tr("Black"); - case 1: return tr("Red"); - case 2: return tr("Blue"); - case 3: return tr("Green"); - case 4: return tr("Purple"); - case 5: return tr("Orange"); + if (m_plotStyle == PlotFilledBlocks) { + return ColourMapper::getColourMapName(value); + } else { + switch (value) { + default: + case 0: return tr("Black"); + case 1: return tr("Red"); + case 2: return tr("Blue"); + case 3: return tr("Green"); + case 4: return tr("Purple"); + case 5: return tr("Orange"); + } } } if (name == "Scale") { @@ -517,6 +549,7 @@ case 0: return tr("Lines"); case 1: return tr("Steps"); case 2: return tr("Blocks"); + case 3: return tr("Colours"); } } if (name == "Bin Scale") { @@ -545,14 +578,18 @@ if (name == "Gain") { setGain(pow(10, float(value)/20.0)); } else if (name == "Colour") { - switch (value) { - default: - case 0: setBaseColour(Qt::black); break; - case 1: setBaseColour(Qt::darkRed); break; - case 2: setBaseColour(Qt::darkBlue); break; - case 3: setBaseColour(Qt::darkGreen); break; - case 4: setBaseColour(QColor(200, 50, 255)); break; - case 5: setBaseColour(QColor(255, 150, 50)); break; + if (m_plotStyle == PlotFilledBlocks) { + setFillColourMap(value); + } else { + switch (value) { + default: + case 0: setBaseColour(Qt::black); break; + case 1: setBaseColour(Qt::darkRed); break; + case 2: setBaseColour(Qt::darkBlue); break; + case 3: setBaseColour(Qt::darkGreen); break; + case 4: setBaseColour(QColor(200, 50, 255)); break; + case 5: setBaseColour(QColor(255, 150, 50)); break; + } } } else if (name == "Scale") { switch (value) { @@ -591,6 +628,14 @@ } void +SliceLayer::setFillColourMap(int map) +{ + if (m_colourMap == map) return; + m_colourMap = map; + emit layerParametersChanged(); +} + +void SliceLayer::setEnergyScale(EnergyScale scale) { if (m_energyScale == scale) return; @@ -610,7 +655,12 @@ SliceLayer::setPlotStyle(PlotStyle style) { if (m_plotStyle == style) return; + bool colourTypeChanged = (style == PlotFilledBlocks || + m_plotStyle == PlotFilledBlocks); m_plotStyle = style; + if (colourTypeChanged) { + emit layerParameterRangesChanged(); + } emit layerParametersChanged(); } @@ -644,11 +694,13 @@ QString s; s += QString("colour=\"%1\" " - "energyScale=\"%2\" " - "samplingMode=\"%3\" " - "gain=\"%4\" " - "normalize=\"%5\"") + "colourScheme=\"%2\" " + "energyScale=\"%3\" " + "samplingMode=\"%4\" " + "gain=\"%5\" " + "normalize=\"%6\"") .arg(encodeColour(m_colour)) + .arg(m_colourMap) .arg(m_energyScale) .arg(m_samplingMode) .arg(m_gain) @@ -678,6 +730,9 @@ attributes.value("samplingMode").toInt(&ok); if (ok) setSamplingMode(mode); + int colourMap = attributes.value("colourScheme").toInt(&ok); + if (ok) setFillColourMap(colourMap); + float gain = attributes.value("gain").toFloat(&ok); if (ok) setGain(gain);
--- a/layer/SliceLayer.h Wed Jan 31 12:13:47 2007 +0000 +++ b/layer/SliceLayer.h Thu Feb 01 14:31:28 2007 +0000 @@ -65,13 +65,16 @@ enum SamplingMode { NearestSample, SampleMean, SamplePeak }; - enum PlotStyle { PlotLines, PlotSteps, PlotBlocks }; + enum PlotStyle { PlotLines, PlotSteps, PlotBlocks, PlotFilledBlocks }; enum BinScale { LinearBins, LogBins, InvertedLogBins }; void setBaseColour(QColor); QColor getBaseColour() const { return m_colour; } + void setFillColourMap(int); + int getFillColourMap() const { return m_colourMap; } + void setEnergyScale(EnergyScale); EnergyScale getEnergyScale() const { return m_energyScale; } @@ -100,6 +103,7 @@ protected: const DenseThreeDimensionalModel *m_sliceableModel; QColor m_colour; + int m_colourMap; EnergyScale m_energyScale; SamplingMode m_samplingMode; PlotStyle m_plotStyle;
--- a/layer/SpectrogramLayer.cpp Wed Jan 31 12:13:47 2007 +0000 +++ b/layer/SpectrogramLayer.cpp Thu Feb 01 14:31:28 2007 +0000 @@ -54,7 +54,7 @@ m_maxFrequency(8000), m_initialMaxFrequency(8000), m_colourScale(dBColourScale), - m_colourScheme(0), + m_colourMap(0), m_frequencyScale(LinearFrequencyScale), m_binDisplay(AllBins), m_normalizeColumns(false), @@ -90,7 +90,7 @@ this, SLOT(preferenceChanged(PropertyContainer::PropertyName))); setWindowType(prefs->getWindowType()); - setColourmap(); + initialisePalette(); } SpectrogramLayer::~SpectrogramLayer() @@ -189,18 +189,12 @@ name == "Window Increment" || name == "Zero Padding") return tr("Window"); if (name == "Colour" || -// name == "Gain" || name == "Threshold" || name == "Colour Rotation") return tr("Colour"); if (name == "Normalize Columns" || name == "Normalize Visible Area" || -// name == "Bin Display" || name == "Gain" || name == "Colour Scale") return tr("Scale"); -// if (name == "Max Frequency" || -// name == "Min Frequency" || -// name == "Frequency Scale" || -// name == "Frequency Adjustment") return tr("Range"); return QString(); } @@ -251,7 +245,7 @@ *min = 0; *max = ColourMapper::getColourMapCount() - 1; - deft = m_colourScheme; + deft = m_colourMap; } else if (name == "Window Size") { @@ -445,7 +439,7 @@ } else if (name == "Colour Rotation") { setColourRotation(value); } else if (name == "Colour") { - setColourScheme(value); + setColourMap(value); } else if (name == "Window Size") { setWindowSize(32 << value); } else if (name == "Window Increment") { @@ -755,7 +749,7 @@ int distance = r - m_colourRotation; if (distance != 0) { - rotateColourmap(-distance); + rotatePalette(-distance); m_colourRotation = r; } @@ -781,22 +775,22 @@ } void -SpectrogramLayer::setColourScheme(int scheme) +SpectrogramLayer::setColourMap(int map) { - if (m_colourScheme == scheme) return; + if (m_colourMap == map) return; invalidatePixmapCaches(); - m_colourScheme = scheme; - setColourmap(); + m_colourMap = map; + initialisePalette(); emit layerParametersChanged(); } int -SpectrogramLayer::getColourScheme() const +SpectrogramLayer::getColourMap() const { - return m_colourScheme; + return m_colourMap; } void @@ -992,46 +986,45 @@ } void -SpectrogramLayer::setColourmap() +SpectrogramLayer::initialisePalette() { int formerRotation = m_colourRotation; - if (m_colourScheme == (int)ColourMapper::BlackOnWhite) { - m_colourMap.setColour(NO_VALUE, Qt::white); + if (m_colourMap == (int)ColourMapper::BlackOnWhite) { + m_palette.setColour(NO_VALUE, Qt::white); } else { - m_colourMap.setColour(NO_VALUE, Qt::black); + m_palette.setColour(NO_VALUE, Qt::black); } - ColourMapper mapper(m_colourScheme, 1.f, 256.f); + ColourMapper mapper(m_colourMap, 1.f, 255.f); for (int pixel = 1; pixel < 256; ++pixel) { - - m_colourMap.setColour(pixel, mapper.map(pixel)); + m_palette.setColour(pixel, mapper.map(pixel)); } m_crosshairColour = mapper.getContrastingColour(); m_colourRotation = 0; - rotateColourmap(m_colourRotation - formerRotation); + rotatePalette(m_colourRotation - formerRotation); m_colourRotation = formerRotation; } void -SpectrogramLayer::rotateColourmap(int distance) +SpectrogramLayer::rotatePalette(int distance) { QColor newPixels[256]; - newPixels[NO_VALUE] = m_colourMap.getColour(NO_VALUE); + newPixels[NO_VALUE] = m_palette.getColour(NO_VALUE); for (int pixel = 1; pixel < 256; ++pixel) { int target = pixel + distance; while (target < 1) target += 255; while (target > 255) target -= 255; - newPixels[target] = m_colourMap.getColour(pixel); + newPixels[target] = m_palette.getColour(pixel); } for (int pixel = 0; pixel < 256; ++pixel) { - m_colourMap.setColour(pixel, newPixels[pixel]); + m_palette.setColour(pixel, newPixels[pixel]); } } @@ -1666,7 +1659,7 @@ void SpectrogramLayer::paint(View *v, QPainter &paint, QRect rect) const { - if (m_colourScheme == (int)ColourMapper::BlackOnWhite) { + if (m_colourMap == (int)ColourMapper::BlackOnWhite) { v->setLightBackground(true); } else { v->setLightBackground(false); @@ -1930,7 +1923,7 @@ m_drawBuffer = QImage(w, h, QImage::Format_RGB32); } - m_drawBuffer.fill(m_colourMap.getColour(0).rgb()); + m_drawBuffer.fill(m_palette.getColour(0).rgb()); int sr = m_model->getSampleRate(); @@ -2108,7 +2101,7 @@ pixel = getDisplayValue(v, avg); assert(x <= m_drawBuffer.width()); - QColor c = m_colourMap.getColour(pixel); + QColor c = m_palette.getColour(pixel); m_drawBuffer.setPixel(x, y, qRgb(c.red(), c.green(), c.blue())); } @@ -2659,7 +2652,7 @@ /* int colour = (i * 255) / ch + 1; */ - paint.setPen(m_colourMap.getColour(colour)); + paint.setPen(m_palette.getColour(colour)); int y = textHeight * topLines + 4 + ch - i; @@ -2939,7 +2932,7 @@ .arg(m_minFrequency) .arg(m_maxFrequency) .arg(m_colourScale) - .arg(m_colourScheme) + .arg(m_colourMap) .arg(m_colourRotation) .arg(m_frequencyScale) .arg(m_binDisplay) @@ -2996,8 +2989,8 @@ attributes.value("colourScale").toInt(&ok); if (ok) setColourScale(colourScale); - int colourScheme = attributes.value("colourScheme").toInt(&ok); - if (ok) setColourScheme(colourScheme); + int colourMap = attributes.value("colourScheme").toInt(&ok); + if (ok) setColourMap(colourMap); int colourRotation = attributes.value("colourRotation").toInt(&ok); if (ok) setColourRotation(colourRotation);
--- a/layer/SpectrogramLayer.h Wed Jan 31 12:13:47 2007 +0000 +++ b/layer/SpectrogramLayer.h Thu Feb 01 14:31:28 2007 +0000 @@ -170,8 +170,8 @@ void setNormalizeVisibleArea(bool n); bool getNormalizeVisibleArea() const; - void setColourScheme(int scheme); - int getColourScheme() const; + void setColourMap(int map); + int getColourMap() const; /** * Specify the colourmap rotation for the colour scale. @@ -238,7 +238,7 @@ size_t m_maxFrequency; size_t m_initialMaxFrequency; ColourScale m_colourScale; - int m_colourScheme; + int m_colourMap; QColor m_crosshairColour; FrequencyScale m_frequencyScale; BinDisplay m_binDisplay; @@ -248,7 +248,7 @@ enum { NO_VALUE = 0 }; // colour index for unused pixels - class ColourMap + class Palette { public: QColor getColour(unsigned char index) const { @@ -263,7 +263,7 @@ QColor m_colours[256]; }; - ColourMap m_colourMap; + Palette m_palette; struct PixmapCache { @@ -283,8 +283,8 @@ mutable size_t m_candidateFillStartFrame; bool m_exiting; - void setColourmap(); - void rotateColourmap(int distance); + void initialisePalette(); + void rotatePalette(int distance); static float calculateFrequency(size_t bin, size_t windowSize,
--- a/layer/TimeValueLayer.cpp Wed Jan 31 12:13:47 2007 +0000 +++ b/layer/TimeValueLayer.cpp Thu Feb 01 14:31:28 2007 +0000 @@ -18,6 +18,7 @@ #include "data/model/Model.h" #include "base/RealTime.h" #include "base/Profiler.h" +#include "base/LogRange.h" #include "view/View.h" #include "data/model/SparseTimeValueModel.h" @@ -26,6 +27,7 @@ #include "widgets/ListInputDialog.h" #include "SpectrogramLayer.h" // for optional frequency alignment +#include "ColourMapper.h" #include <QPainter> #include <QPainterPath> @@ -43,6 +45,7 @@ m_editingPoint(0, 0.0, tr("New Point")), m_editingCommand(0), m_colour(Qt::darkGreen), + m_colourMap(0), m_plotStyle(PlotConnectedPoints), m_verticalScale(AutoAlignScale) { @@ -105,15 +108,25 @@ if (name == "Colour") { - if (min) *min = 0; - if (max) *max = 5; + if (m_plotStyle == PlotSegmentation) { + + if (min) *min = 0; + if (max) *max = ColourMapper::getColourMapCount() - 1; - if (m_colour == Qt::black) deft = 0; - else if (m_colour == Qt::darkRed) deft = 1; - else if (m_colour == Qt::darkBlue) deft = 2; - else if (m_colour == Qt::darkGreen) deft = 3; - else if (m_colour == QColor(200, 50, 255)) deft = 4; - else if (m_colour == QColor(255, 150, 50)) deft = 5; + deft = m_colourMap; + + } else { + + if (min) *min = 0; + if (max) *max = 5; + + if (m_colour == Qt::black) deft = 0; + else if (m_colour == Qt::darkRed) deft = 1; + else if (m_colour == Qt::darkBlue) deft = 2; + else if (m_colour == Qt::darkGreen) deft = 3; + else if (m_colour == QColor(200, 50, 255)) deft = 4; + else if (m_colour == QColor(255, 150, 50)) deft = 5; + } } else if (name == "Plot Type") { @@ -149,15 +162,19 @@ int value) const { if (name == "Colour") { - switch (value) { - default: - case 0: return tr("Black"); - case 1: return tr("Red"); - case 2: return tr("Blue"); - case 3: return tr("Green"); - case 4: return tr("Purple"); - case 5: return tr("Orange"); - } + if (m_plotStyle == PlotSegmentation) { + return ColourMapper::getColourMapName(value); + } else { + switch (value) { + default: + case 0: return tr("Black"); + case 1: return tr("Red"); + case 2: return tr("Blue"); + case 3: return tr("Green"); + case 4: return tr("Purple"); + case 5: return tr("Orange"); + } + } } else if (name == "Plot Type") { switch (value) { default: @@ -184,15 +201,19 @@ TimeValueLayer::setProperty(const PropertyName &name, int value) { if (name == "Colour") { - switch (value) { - default: - case 0: setBaseColour(Qt::black); break; - case 1: setBaseColour(Qt::darkRed); break; - case 2: setBaseColour(Qt::darkBlue); break; - case 3: setBaseColour(Qt::darkGreen); break; - case 4: setBaseColour(QColor(200, 50, 255)); break; - case 5: setBaseColour(QColor(255, 150, 50)); break; - } + if (m_plotStyle == PlotSegmentation) { + setFillColourMap(value); + } else { + switch (value) { + default: + case 0: setBaseColour(Qt::black); break; + case 1: setBaseColour(Qt::darkRed); break; + case 2: setBaseColour(Qt::darkBlue); break; + case 3: setBaseColour(Qt::darkGreen); break; + case 4: setBaseColour(QColor(200, 50, 255)); break; + case 5: setBaseColour(QColor(255, 150, 50)); break; + } + } } else if (name == "Plot Type") { setPlotStyle(PlotStyle(value)); } else if (name == "Vertical Scale") { @@ -215,10 +236,23 @@ } void +TimeValueLayer::setFillColourMap(int map) +{ + if (m_colourMap == map) return; + m_colourMap = map; + emit layerParametersChanged(); +} + +void TimeValueLayer::setPlotStyle(PlotStyle style) { if (m_plotStyle == style) return; + bool colourTypeChanged = (style == PlotSegmentation || + m_plotStyle == PlotSegmentation); m_plotStyle = style; + if (colourTypeChanged) { + emit layerParameterRangesChanged(); + } emit layerParametersChanged(); } @@ -436,8 +470,7 @@ min = m_model->getValueMinimum(); max = m_model->getValueMaximum(); } else if (log) { - min = (min < 0.0) ? -log10(-min) : (min == 0.0) ? 0.0 : log10(min); - max = (max < 0.0) ? -log10(-max) : (max == 0.0) ? 0.0 : log10(max); + LogRange::mapRange(min, max); } } else if (m_verticalScale == PlusMinusOneScale) { @@ -451,8 +484,7 @@ max = m_model->getValueMaximum(); if (m_verticalScale == LogScale) { - min = (min < 0.0) ? -log10(-min) : (min == 0.0) ? 0.0 : log10(min); - max = (max < 0.0) ? -log10(-max) : (max == 0.0) ? 0.0 : log10(max); + LogRange::mapRange(min, max); log = true; } } @@ -473,7 +505,7 @@ // << max << ", log " << logarithmic << std::endl; if (logarithmic) { - val = (val < 0.0) ? -log10(-val) : (val == 0.0) ? 0.0 : log10(val); + val = LogRange::map(val); } return int(h - ((val - min) * h) / (max - min)); @@ -491,7 +523,7 @@ float val = min + (float(h - y) * float(max - min)) / h; if (logarithmic) { - val = pow(10, val); + val = powf(10.f, val); } return val; @@ -504,14 +536,21 @@ bool log; getScaleExtents(v, min, max, log); + float logthresh = -80; + + if (min > max) std::swap(min, max); + if (max == min) max = min + 1; + if (log) { - val = (val < 0.0) ? -log10(-val) : (val == 0.0) ? 0.0 : log10(val); + LogRange::mapRange(min, max); + val = LogRange::map(val); } - int iv = ((val - min) / (max - min)) * 255.999; +// std::cerr << "TimeValueLayer::getColourForValue: min " << min << ", max " +// << max << ", log " << log << ", value " << val << std::endl; - QColor colour = QColor::fromHsv(256 - iv, iv / 2 + 128, iv); - return QColor(colour.red(), colour.green(), colour.blue(), 120); + QColor solid = ColourMapper(m_colourMap, min, max).map(val); + return QColor(solid.red(), solid.green(), solid.blue(), 120); } void @@ -608,6 +647,7 @@ paint.setPen(m_colour); if (m_plotStyle == PlotSegmentation) { + paint.setPen(Qt::black); paint.setBrush(getColourForValue(v, p.value)); labelY = v->height(); } else if (m_plotStyle == PlotLines ||
--- a/layer/TimeValueLayer.h Wed Jan 31 12:13:47 2007 +0000 +++ b/layer/TimeValueLayer.h Thu Feb 01 14:31:28 2007 +0000 @@ -76,6 +76,9 @@ void setBaseColour(QColor); QColor getBaseColour() const { return m_colour; } + void setFillColourMap(int); + int getFillColourMap() const { return m_colourMap; } + enum PlotStyle { PlotPoints, PlotStems, @@ -132,6 +135,7 @@ SparseTimeValueModel::Point m_editingPoint; SparseTimeValueModel::EditCommand *m_editingCommand; QColor m_colour; + int m_colourMap; PlotStyle m_plotStyle; VerticalScale m_verticalScale; };
--- a/view/View.cpp Wed Jan 31 12:13:47 2007 +0000 +++ b/view/View.cpp Thu Feb 01 14:31:28 2007 +0000 @@ -450,6 +450,8 @@ connect(layer, SIGNAL(layerParametersChanged()), this, SLOT(layerParametersChanged())); + connect(layer, SIGNAL(layerParameterRangesChanged()), + this, SLOT(layerParameterRangesChanged())); connect(layer, SIGNAL(layerNameChanged()), this, SLOT(layerNameChanged())); connect(layer, SIGNAL(modelChanged()), @@ -487,6 +489,21 @@ } } + disconnect(layer, SIGNAL(layerParametersChanged()), + this, SLOT(layerParametersChanged())); + disconnect(layer, SIGNAL(layerParameterRangesChanged()), + this, SLOT(layerParameterRangesChanged())); + disconnect(layer, SIGNAL(layerNameChanged()), + this, SLOT(layerNameChanged())); + disconnect(layer, SIGNAL(modelChanged()), + this, SLOT(modelChanged())); + disconnect(layer, SIGNAL(modelCompletionChanged()), + this, SLOT(modelCompletionChanged())); + disconnect(layer, SIGNAL(modelChanged(size_t, size_t)), + this, SLOT(modelChanged(size_t, size_t))); + disconnect(layer, SIGNAL(modelReplaced()), + this, SLOT(modelReplaced())); + update(); emit propertyContainerRemoved(layer); @@ -734,6 +751,13 @@ } void +View::layerParameterRangesChanged() +{ + Layer *layer = dynamic_cast<Layer *>(sender()); + if (layer) emit propertyContainerPropertyRangeChanged(layer); +} + +void View::layerNameChanged() { Layer *layer = dynamic_cast<Layer *>(sender());
--- a/view/View.h Wed Jan 31 12:13:47 2007 +0000 +++ b/view/View.h Thu Feb 01 14:31:28 2007 +0000 @@ -236,6 +236,7 @@ void propertyContainerAdded(PropertyContainer *pc); void propertyContainerRemoved(PropertyContainer *pc); void propertyContainerPropertyChanged(PropertyContainer *pc); + void propertyContainerPropertyRangeChanged(PropertyContainer *pc); void propertyContainerNameChanged(PropertyContainer *pc); void propertyChanged(PropertyContainer::PropertyName); @@ -250,6 +251,7 @@ virtual void modelCompletionChanged(); virtual void modelReplaced(); virtual void layerParametersChanged(); + virtual void layerParameterRangesChanged(); virtual void layerNameChanged(); virtual void viewManagerCentreFrameChanged(void *, unsigned long, bool);
--- a/widgets/PropertyBox.cpp Wed Jan 31 12:13:47 2007 +0000 +++ b/widgets/PropertyBox.cpp Thu Feb 01 14:31:28 2007 +0000 @@ -248,7 +248,8 @@ } void -PropertyBox::updatePropertyEditor(PropertyContainer::PropertyName name) +PropertyBox::updatePropertyEditor(PropertyContainer::PropertyName name, + bool rangeChanged) { PropertyContainer::PropertyType type = m_container->getPropertyType(name); int row = m_layout->rowCount(); @@ -339,6 +340,14 @@ if (have) { dial = dynamic_cast<AudioDial *>(m_propertyControllers[name]); assert(dial); + if (rangeChanged) { + dial->blockSignals(true); + dial->setMinimum(min); + dial->setMaximum(max); + dial->setRangeMapper(m_container->getNewPropertyRangeMapper(name)); + dial->blockSignals(false); + } + } else { #ifdef DEBUG_PROPERTY_BOX std::cerr << "PropertyBox: creating new dial" << std::endl; @@ -401,7 +410,11 @@ cb = new NotifyingComboBox(); cb->setObjectName(name); cb->setDuplicatesEnabled(false); + } + if (!have || rangeChanged) { + cb->blockSignals(true); + cb->clear(); if (type == PropertyContainer::ValueProperty) { for (int i = min; i <= max; ++i) { cb->addItem(m_container->getPropertyValueLabel(name, i)); @@ -414,7 +427,10 @@ } cb->setEditable(true); } + cb->blockSignals(false); + } + if (!have) { connect(cb, SIGNAL(activated(int)), this, SLOT(propertyControllerChanged(int))); connect(cb, SIGNAL(mouseEntered()), @@ -484,6 +500,19 @@ } void +PropertyBox::propertyContainerPropertyRangeChanged(PropertyContainer *pc) +{ + blockSignals(true); + + PropertyContainer::PropertyList properties = m_container->getProperties(); + for (size_t i = 0; i < properties.size(); ++i) { + updatePropertyEditor(properties[i], true); + } + + blockSignals(false); +} + +void PropertyBox::unitDatabaseChanged() { blockSignals(true);
--- a/widgets/PropertyBox.h Wed Jan 31 12:13:47 2007 +0000 +++ b/widgets/PropertyBox.h Thu Feb 01 14:31:28 2007 +0000 @@ -48,6 +48,7 @@ public slots: void propertyContainerPropertyChanged(PropertyContainer *); + void propertyContainerPropertyRangeChanged(PropertyContainer *); void pluginConfigurationChanged(QString); void layerVisibilityChanged(bool); @@ -69,7 +70,8 @@ void mouseLeftWidget(); protected: - void updatePropertyEditor(PropertyContainer::PropertyName); + void updatePropertyEditor(PropertyContainer::PropertyName, + bool rangeChanged = false); QLabel *m_nameWidget; QWidget *m_mainWidget;
--- a/widgets/PropertyStack.cpp Wed Jan 31 12:13:47 2007 +0000 +++ b/widgets/PropertyStack.cpp Thu Feb 01 14:31:28 2007 +0000 @@ -54,6 +54,9 @@ connect(m_client, SIGNAL(propertyContainerPropertyChanged(PropertyContainer *)), this, SLOT(propertyContainerPropertyChanged(PropertyContainer *))); + connect(m_client, SIGNAL(propertyContainerPropertyRangeChanged(PropertyContainer *)), + this, SLOT(propertyContainerPropertyRangeChanged(PropertyContainer *))); + connect(m_client, SIGNAL(propertyContainerNameChanged(PropertyContainer *)), this, SLOT(propertyContainerNameChanged(PropertyContainer *))); @@ -157,6 +160,16 @@ } void +PropertyStack::propertyContainerPropertyRangeChanged(PropertyContainer *pc) +{ + for (unsigned int i = 0; i < m_boxes.size(); ++i) { + if (pc == m_boxes[i]->getContainer()) { + m_boxes[i]->propertyContainerPropertyRangeChanged(pc); + } + } +} + +void PropertyStack::propertyContainerNameChanged(PropertyContainer *pc) { if (sender() != m_client) return;
--- a/widgets/PropertyStack.h Wed Jan 31 12:13:47 2007 +0000 +++ b/widgets/PropertyStack.h Thu Feb 01 14:31:28 2007 +0000 @@ -45,6 +45,7 @@ void propertyContainerAdded(PropertyContainer *); void propertyContainerRemoved(PropertyContainer *); void propertyContainerPropertyChanged(PropertyContainer *); + void propertyContainerPropertyRangeChanged(PropertyContainer *); void propertyContainerNameChanged(PropertyContainer *); void showLayer(bool);