# HG changeset patch # User Chris Cannam # Date 1147444843 0 # Node ID 0f36cdf407a684653a2b7cf496272b1d417169d4 # Parent 0db5e7492ce8fb92fdee6596513de5a01309dc16 * Make vertical scale alignment modes work in note layer as well as time-value layer, and several significant fixes to it * Make it possible to draw notes properly on the note layer * Show units (and frequencies etc in note layer's case) in the time-value and note layer description boxes * Minor fix to item edit dialog layout * Some minor menu rearrangement * Comment out a lot of debug output * Add SV website and reference URLs to Help menu, and add code to (attempt to) open them in the user's preferred browser diff -r 0db5e7492ce8 -r 0f36cdf407a6 layer/Colour3DPlotLayer.h --- a/layer/Colour3DPlotLayer.h Thu May 11 15:02:14 2006 +0000 +++ b/layer/Colour3DPlotLayer.h Fri May 12 14:40:43 2006 +0000 @@ -64,7 +64,7 @@ virtual int getCompletion() const { return m_model->getCompletion(); } - virtual bool getValueExtents(float &, float &, QString &) const { return false; } + virtual bool getValueExtents(float &, float &, bool &, QString &) const { return false; } virtual QString getPropertyLabel(const PropertyName &) const { return ""; } /* diff -r 0db5e7492ce8 -r 0f36cdf407a6 layer/LayerFactory.cpp --- a/layer/LayerFactory.cpp Thu May 11 15:02:14 2006 +0000 +++ b/layer/LayerFactory.cpp Fri May 12 14:40:43 2006 +0000 @@ -315,8 +315,8 @@ std::cerr << "LayerFactory::createLayer: Unknown layer type " << type << std::endl; } else { - std::cerr << "LayerFactory::createLayer: Setting object name " - << getLayerPresentationName(type).toStdString() << " on " << layer << std::endl; +// std::cerr << "LayerFactory::createLayer: Setting object name " +// << getLayerPresentationName(type).toStdString() << " on " << layer << std::endl; layer->setObjectName(getLayerPresentationName(type)); } diff -r 0db5e7492ce8 -r 0f36cdf407a6 layer/NoteLayer.cpp --- a/layer/NoteLayer.cpp Thu May 11 15:02:14 2006 +0000 +++ b/layer/NoteLayer.cpp Fri May 12 14:40:43 2006 +0000 @@ -42,7 +42,7 @@ m_editingPoint(0, 0.0, 0, tr("New Point")), m_editingCommand(0), m_colour(Qt::black), - m_verticalScale(MinMaxRangeScale) + m_verticalScale(AutoAlignScale) { } @@ -60,7 +60,7 @@ connect(m_model, SIGNAL(completionChanged()), this, SIGNAL(modelCompletionChanged())); - std::cerr << "NoteLayer::setModel(" << model << ")" << std::endl; +// std::cerr << "NoteLayer::setModel(" << model << ")" << std::endl; emit modelReplaced(); } @@ -114,7 +114,7 @@ } else if (name == "Vertical Scale") { if (min) *min = 0; - if (max) *max = 2; + if (max) *max = 3; deft = int(m_verticalScale); @@ -150,9 +150,10 @@ } else if (name == "Vertical Scale") { switch (value) { default: - case 0: return tr("Note Range In Use"); - case 1: return tr("MIDI Note Range"); - case 2: return tr("Frequency"); + case 0: return tr("Auto-Align"); + case 1: return tr("Linear Scale"); + case 2: return tr("Log Scale"); + case 3: return tr("MIDI Note Range"); } } return tr(""); @@ -206,12 +207,52 @@ } bool -NoteLayer::getValueExtents(float &min, float &max, QString &unit) const +NoteLayer::shouldConvertMIDIToHz() const +{ + QString unit = m_model->getScaleUnits(); + return (unit != "Hz"); +// if (unit == "" || +// unit.startsWith("MIDI") || +// unit.startsWith("midi")) return true; +// return false; +} + +bool +NoteLayer::getValueExtents(float &min, float &max, + bool &logarithmic, QString &unit) const { if (!m_model) return false; min = m_model->getValueMinimum(); max = m_model->getValueMaximum(); - unit = m_model->getScaleUnits(); + + if (shouldConvertMIDIToHz()) unit = "Hz"; + else unit = m_model->getScaleUnits(); + + if (m_verticalScale == MIDIRangeScale || + m_verticalScale == LogScale) logarithmic = true; + + return true; +} + +bool +NoteLayer::getDisplayExtents(float &min, float &max) const +{ + if (!m_model || m_verticalScale == AutoAlignScale) return false; + + if (m_verticalScale == MIDIRangeScale) { + min = Pitch::getFrequencyForPitch(0); + max = Pitch::getFrequencyForPitch(127); + return true; + } + + min = m_model->getValueMinimum(); + max = m_model->getValueMaximum(); + + if (shouldConvertMIDIToHz()) { + min = Pitch::getFrequencyForPitch(lrintf(min)); + max = Pitch::getFrequencyForPitch(lrintf(max + 1)); + } + return true; } @@ -301,17 +342,38 @@ RealTime rd = RealTime::frame2RealTime(note.duration, m_model->getSampleRate()); + QString pitchText; + + if (shouldConvertMIDIToHz()) { + + int mnote = lrintf(note.value); + int cents = lrintf((note.value - mnote) * 100); + float freq = Pitch::getFrequencyForPitch(mnote, cents); + pitchText = QString("%1 (%2 Hz)") + .arg(Pitch::getPitchLabel(mnote, cents)).arg(freq); + + } else if (m_model->getScaleUnits() == "Hz") { + + pitchText = QString("%1 Hz (%2)") + .arg(note.value) + .arg(Pitch::getPitchLabelForFrequency(note.value)); + + } else { + pitchText = QString("%1 %2") + .arg(note.value).arg(m_model->getScaleUnits()); + } + QString text; if (note.label == "") { text = QString(tr("Time:\t%1\nPitch:\t%2\nDuration:\t%3\nNo label")) .arg(rt.toText(true).c_str()) - .arg(note.value) + .arg(pitchText) .arg(rd.toText(true).c_str()); } else { text = QString(tr("Time:\t%1\nPitch:\t%2\nDuration:\t%3\nLabel:\t%4")) .arg(rt.toText(true).c_str()) - .arg(note.value) + .arg(pitchText) .arg(rd.toText(true).c_str()) .arg(note.label); } @@ -393,66 +455,107 @@ return found; } -int -NoteLayer::getYForValue(View *v, float value) const +void +NoteLayer::getScaleExtents(View *v, float &min, float &max, bool &log) const { - float min, max, h = v->height(); + min = 0.0; + max = 0.0; + log = false; - switch (m_verticalScale) { + QString queryUnits; + if (shouldConvertMIDIToHz()) queryUnits = "Hz"; + else queryUnits = m_model->getScaleUnits(); - case MIDIRangeScale: - min = 0.0; - max = 127.0; - break; + if (m_verticalScale == AutoAlignScale) { - case MinMaxRangeScale: - min = m_model->getValueMinimum(); - max = m_model->getValueMaximum(); - break; + if (!v->getValueExtents(queryUnits, min, max, log)) { - case FrequencyScale: - - value = Pitch::getFrequencyForPitch(lrintf(value), - value - lrintf(value)); + min = m_model->getValueMinimum(); + max = m_model->getValueMaximum(); - // If we have a spectrogram layer on the same view as us, align - // ourselves with it... - for (int i = 0; i < v->getLayerCount(); ++i) { - SpectrogramLayer *spectrogram = dynamic_cast - (v->getLayer(i)); - if (spectrogram) { - return spectrogram->getYForFrequency(v, value); - } - } + if (shouldConvertMIDIToHz()) { + min = Pitch::getFrequencyForPitch(lrintf(min)); + max = Pitch::getFrequencyForPitch(lrintf(max + 1)); + } - // ...otherwise just interpolate - std::cerr << "FrequencyScale: value in = " << value << std::endl; - min = m_model->getValueMinimum(); - min = Pitch::getFrequencyForPitch(lrintf(min), min - lrintf(min)); - max = m_model->getValueMaximum(); - max = Pitch::getFrequencyForPitch(lrintf(max), max - lrintf(max)); - std::cerr << "FrequencyScale: min = " << min << ", max = " << max << ", value = " << value << std::endl; - break; + } else if (log) { + +// std::cerr << "NoteLayer[" << this << "]::getScaleExtents: min = " << min << ", max = " << max << ", log = " << log << std::endl; + + 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); + } + + } else { + + min = m_model->getValueMinimum(); + max = m_model->getValueMaximum(); + + if (m_verticalScale == MIDIRangeScale) { + min = Pitch::getFrequencyForPitch(0); + max = Pitch::getFrequencyForPitch(127); + } else if (shouldConvertMIDIToHz()) { + min = Pitch::getFrequencyForPitch(lrintf(min)); + max = Pitch::getFrequencyForPitch(lrintf(max + 1)); + } + + 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); + log = true; + } } - if (max < min) max = min; - max = max + 1.0; + if (max == min) max = min + 1.0; +} - return int(h - ((value - min) * h) / (max - min)) - 1; +int +NoteLayer::getYForValue(View *v, float val) const +{ + float min = 0.0, max = 0.0; + bool logarithmic = false; + int h = v->height(); + + getScaleExtents(v, min, max, logarithmic); + +// std::cerr << "NoteLayer[" << this << "]::getYForValue(" << val << "): min = " << min << ", max = " << max << ", log = " << logarithmic << std::endl; + + if (shouldConvertMIDIToHz()) { + val = Pitch::getFrequencyForPitch(lrintf(val), + lrintf((val - lrintf(val)) * 100)); +// std::cerr << "shouldConvertMIDIToHz true, val now = " << val << std::endl; + } + + if (logarithmic) { + val = (val < 0.0) ? -log10(-val) : (val == 0.0) ? 0.0 : log10(val); +// std::cerr << "logarithmic true, val now = " << val << std::endl; + } + + int y = int(h - ((val - min) * h) / (max - min)) - 1; +// std::cerr << "y = " << y << std::endl; + return y; } float NoteLayer::getValueForY(View *v, int y) const { - //!!! - - float min = m_model->getValueMinimum(); - float max = m_model->getValueMaximum(); - if (max == min) max = min + 1.0; - + float min = 0.0, max = 0.0; + bool logarithmic = false; int h = v->height(); - return min + (float(h - y) * float(max - min)) / h; + getScaleExtents(v, min, max, logarithmic); + + float val = min + (float(h - y) * float(max - min)) / h; + + if (logarithmic) { + val = pow(10, val); + } + + if (shouldConvertMIDIToHz()) { + val = Pitch::getPitchForFrequency(val); + } + + return val; } void @@ -538,7 +641,7 @@ void NoteLayer::drawStart(View *v, QMouseEvent *e) { - std::cerr << "NoteLayer::drawStart(" << e->x() << "," << e->y() << ")" << std::endl; +// std::cerr << "NoteLayer::drawStart(" << e->x() << "," << e->y() << ")" << std::endl; if (!m_model) return; @@ -562,7 +665,7 @@ void NoteLayer::drawDrag(View *v, QMouseEvent *e) { - std::cerr << "NoteLayer::drawDrag(" << e->x() << "," << e->y() << ")" << std::endl; +// std::cerr << "NoteLayer::drawDrag(" << e->x() << "," << e->y() << ")" << std::endl; if (!m_model || !m_editing) return; @@ -570,18 +673,28 @@ if (frame < 0) frame = 0; frame = frame / m_model->getResolution() * m_model->getResolution(); - float value = getValueForY(v, e->y()); + float newValue = getValueForY(v, e->y()); + + long newFrame = m_editingPoint.frame; + long newDuration = frame - newFrame; + if (newDuration < 0) { + newFrame = frame; + newDuration = -newDuration; + } else if (newDuration == 0) { + newDuration = 1; + } m_editingCommand->deletePoint(m_editingPoint); - m_editingPoint.frame = frame; - m_editingPoint.value = value; + m_editingPoint.frame = newFrame; + m_editingPoint.value = newValue; + m_editingPoint.duration = newDuration; m_editingCommand->addPoint(m_editingPoint); } void NoteLayer::drawEnd(View *v, QMouseEvent *e) { - std::cerr << "NoteLayer::drawEnd(" << e->x() << "," << e->y() << ")" << std::endl; +// std::cerr << "NoteLayer::drawEnd(" << e->x() << "," << e->y() << ")" << std::endl; if (!m_model || !m_editing) return; m_editingCommand->finish(); m_editingCommand = 0; @@ -591,7 +704,7 @@ void NoteLayer::editStart(View *v, QMouseEvent *e) { - std::cerr << "NoteLayer::editStart(" << e->x() << "," << e->y() << ")" << std::endl; +// std::cerr << "NoteLayer::editStart(" << e->x() << "," << e->y() << ")" << std::endl; if (!m_model) return; @@ -612,7 +725,7 @@ void NoteLayer::editDrag(View *v, QMouseEvent *e) { - std::cerr << "NoteLayer::editDrag(" << e->x() << "," << e->y() << ")" << std::endl; +// std::cerr << "NoteLayer::editDrag(" << e->x() << "," << e->y() << ")" << std::endl; if (!m_model || !m_editing) return; @@ -636,7 +749,7 @@ void NoteLayer::editEnd(View *v, QMouseEvent *e) { - std::cerr << "NoteLayer::editEnd(" << e->x() << "," << e->y() << ")" << std::endl; +// std::cerr << "NoteLayer::editEnd(" << e->x() << "," << e->y() << ")" << std::endl; if (!m_model || !m_editing) return; if (m_editingCommand) { diff -r 0db5e7492ce8 -r 0f36cdf407a6 layer/NoteLayer.h --- a/layer/NoteLayer.h Thu May 11 15:02:14 2006 +0000 +++ b/layer/NoteLayer.h Fri May 12 14:40:43 2006 +0000 @@ -73,9 +73,10 @@ QColor getBaseColour() const { return m_colour; } enum VerticalScale { - MinMaxRangeScale, - MIDIRangeScale, - FrequencyScale + AutoAlignScale, + LinearScale, + LogScale, + MIDIRangeScale }; void setVerticalScale(VerticalScale scale); @@ -87,7 +88,10 @@ virtual int getCompletion() const { return m_model->getCompletion(); } - virtual bool getValueExtents(float &min, float &max, QString &unit) const; + virtual bool getValueExtents(float &min, float &max, + bool &log, QString &unit) const; + + virtual bool getDisplayExtents(float &min, float &max) const; virtual QString toXmlString(QString indent = "", QString extraAttributes = "") const; @@ -95,8 +99,10 @@ void setProperties(const QXmlAttributes &attributes); 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; NoteModel::PointList getLocalPoints(View *v, int) const; diff -r 0db5e7492ce8 -r 0f36cdf407a6 layer/SpectrogramLayer.cpp --- a/layer/SpectrogramLayer.cpp Thu May 11 15:02:14 2006 +0000 +++ b/layer/SpectrogramLayer.cpp Fri May 12 14:40:43 2006 +0000 @@ -34,7 +34,7 @@ #include #include -#define DEBUG_SPECTROGRAM_REPAINT 1 +//#define DEBUG_SPECTROGRAM_REPAINT 1 static double mod(double x, double y) { @@ -111,7 +111,7 @@ void SpectrogramLayer::setModel(const DenseTimeValueModel *model) { - std::cerr << "SpectrogramLayer(" << this << "): setModel(" << model << ")" << std::endl; +// std::cerr << "SpectrogramLayer(" << this << "): setModel(" << model << ")" << std::endl; m_mutex.lock(); m_cacheInvalid = true; @@ -637,8 +637,8 @@ void SpectrogramLayer::setGain(float gain) { - std::cerr << "SpectrogramLayer::setGain(" << gain << ") (my gain is now " - << m_gain << ")" << std::endl; +// std::cerr << "SpectrogramLayer::setGain(" << gain << ") (my gain is now " +// << m_gain << ")" << std::endl; if (m_gain == gain) return; @@ -1292,18 +1292,18 @@ m_fillExtent = 0; m_fillCompletion = 0; - std::cerr << "SpectrogramLayer::CacheFillThread::run: model is ready" << std::endl; + // std::cerr << "SpectrogramLayer::CacheFillThread::run: model is ready" << std::endl; size_t start = m_layer.m_model->getStartFrame(); size_t end = m_layer.m_model->getEndFrame(); - std::cerr << "start = " << start << ", end = " << end << std::endl; + // std::cerr << "start = " << start << ", end = " << end << std::endl; WindowType windowType = m_layer.m_windowType; size_t windowSize = m_layer.m_windowSize; size_t windowIncrement = m_layer.getWindowIncrement(); - std::cerr << "\nWINDOW INCREMENT: " << windowIncrement << " (for hop level " << m_layer.m_windowHopLevel << ")\n" << std::endl; + // std::cerr << "\nWINDOW INCREMENT: " << windowIncrement << " (for hop level " << m_layer.m_windowHopLevel << ")\n" << std::endl; size_t visibleStart = m_layer.m_candidateFillStartFrame; visibleStart = (visibleStart / windowIncrement) * windowIncrement; @@ -2174,15 +2174,25 @@ } bool -SpectrogramLayer::getValueExtents(float &min, float &max, QString &unit) const +SpectrogramLayer::getValueExtents(float &min, float &max, + bool &logarithmic, QString &unit) const { min = getEffectiveMinFrequency(); max = getEffectiveMaxFrequency(); + logarithmic = (m_frequencyScale == LogFrequencyScale); unit = "Hz"; return true; } bool +SpectrogramLayer::getDisplayExtents(float &min, float &max) const +{ + min = getEffectiveMinFrequency(); + max = getEffectiveMaxFrequency(); + return true; +} + +bool SpectrogramLayer::snapToFeatureFrame(View *v, int &frame, size_t &resolution, SnapType snap) const diff -r 0db5e7492ce8 -r 0f36cdf407a6 layer/SpectrogramLayer.h --- a/layer/SpectrogramLayer.h Thu May 11 15:02:14 2006 +0000 +++ b/layer/SpectrogramLayer.h Fri May 12 14:40:43 2006 +0000 @@ -186,7 +186,10 @@ virtual int getCompletion() const; - virtual bool getValueExtents(float &min, float &max, QString &unit) const; + virtual bool getValueExtents(float &min, float &max, + bool &logarithmic, QString &unit) const; + + virtual bool getDisplayExtents(float &min, float &max) const; virtual QString toXmlString(QString indent = "", QString extraAttributes = "") const; diff -r 0db5e7492ce8 -r 0f36cdf407a6 layer/TextLayer.cpp --- a/layer/TextLayer.cpp Thu May 11 15:02:14 2006 +0000 +++ b/layer/TextLayer.cpp Fri May 12 14:40:43 2006 +0000 @@ -143,7 +143,8 @@ } bool -TextLayer::getValueExtents(float &min, float &max, QString &unit) const +TextLayer::getValueExtents(float &min, float &max, + bool &logarithmic, QString &unit) const { return false; } diff -r 0db5e7492ce8 -r 0f36cdf407a6 layer/TextLayer.h --- a/layer/TextLayer.h Thu May 11 15:02:14 2006 +0000 +++ b/layer/TextLayer.h Fri May 12 14:40:43 2006 +0000 @@ -78,7 +78,8 @@ virtual int getCompletion() const { return m_model->getCompletion(); } - virtual bool getValueExtents(float &min, float &max, QString &unit) const; + virtual bool getValueExtents(float &min, float &max, + bool &logarithmic, QString &unit) const; virtual QString toXmlString(QString indent = "", QString extraAttributes = "") const; diff -r 0db5e7492ce8 -r 0f36cdf407a6 layer/TimeInstantLayer.h --- a/layer/TimeInstantLayer.h Thu May 11 15:02:14 2006 +0000 +++ b/layer/TimeInstantLayer.h Fri May 12 14:40:43 2006 +0000 @@ -88,7 +88,8 @@ virtual bool needsTextLabelHeight() const { return m_model->hasTextLabels(); } - virtual bool getValueExtents(float &min, float &max, QString &unit) const { + virtual bool getValueExtents(float &min, float &max, + bool &log, QString &unit) const { return false; } diff -r 0db5e7492ce8 -r 0f36cdf407a6 layer/TimeRulerLayer.h --- a/layer/TimeRulerLayer.h Thu May 11 15:02:14 2006 +0000 +++ b/layer/TimeRulerLayer.h Fri May 12 14:40:43 2006 +0000 @@ -53,7 +53,8 @@ int value) const; virtual void setProperty(const PropertyName &, int value); - virtual bool getValueExtents(float &min, float &max, QString &unit) const { + virtual bool getValueExtents(float &min, float &max, + bool &log, QString &unit) const { return false; } diff -r 0db5e7492ce8 -r 0f36cdf407a6 layer/TimeValueLayer.cpp --- a/layer/TimeValueLayer.cpp Thu May 11 15:02:14 2006 +0000 +++ b/layer/TimeValueLayer.cpp Fri May 12 14:40:43 2006 +0000 @@ -42,7 +42,7 @@ m_editingCommand(0), m_colour(Qt::darkGreen), m_plotStyle(PlotConnectedPoints), - m_verticalScale(LinearScale) + m_verticalScale(AutoAlignScale) { } @@ -60,7 +60,7 @@ connect(m_model, SIGNAL(completionChanged()), this, SIGNAL(modelCompletionChanged())); - std::cerr << "TimeValueLayer::setModel(" << model << ")" << std::endl; +// std::cerr << "TimeValueLayer::setModel(" << model << ")" << std::endl; emit modelReplaced(); } @@ -169,10 +169,10 @@ } else if (name == "Vertical Scale") { switch (value) { default: - case 0: return tr("Linear Scale"); - case 1: return tr("Log Scale"); - case 2: return tr("+/-1 Scale"); - case 3: return tr("Frequency Scale"); + case 0: return tr("Auto-Align"); + case 1: return tr("Linear Scale"); + case 2: return tr("Log Scale"); + case 3: return tr("+/-1 Scale"); } } return tr(""); @@ -242,14 +242,27 @@ } bool -TimeValueLayer::getValueExtents(float &min, float &max, QString &unit) const +TimeValueLayer::getValueExtents(float &min, float &max, + bool &logarithmic, QString &unit) const { + if (!m_model) return false; min = m_model->getValueMinimum(); max = m_model->getValueMaximum(); + logarithmic = (m_verticalScale == LogScale); unit = m_model->getScaleUnits(); return true; } +bool +TimeValueLayer::getDisplayExtents(float &min, float &max) const +{ + if (!m_model || m_verticalScale == AutoAlignScale) return false; + + min = m_model->getValueMinimum(); + max = m_model->getValueMaximum(); + return true; +} + SparseTimeValueModel::PointList TimeValueLayer::getLocalPoints(View *v, int x) const { @@ -315,15 +328,19 @@ RealTime rt = RealTime::frame2RealTime(useFrame, m_model->getSampleRate()); QString text; + QString unit = m_model->getScaleUnits(); + if (unit != "") unit = " " + unit; if (points.begin()->label == "") { - text = QString(tr("Time:\t%1\nValue:\t%2\nNo label")) - .arg(rt.toText(true).c_str()) - .arg(points.begin()->value); - } else { - text = QString(tr("Time:\t%1\nValue:\t%2\nLabel:\t%3")) + text = QString(tr("Time:\t%1\nValue:\t%2%3\nNo label")) .arg(rt.toText(true).c_str()) .arg(points.begin()->value) + .arg(unit); + } else { + text = QString(tr("Time:\t%1\nValue:\t%2%3\nLabel:\t%4")) + .arg(rt.toText(true).c_str()) + .arg(points.begin()->value) + .arg(unit) .arg(points.begin()->label); } @@ -404,81 +421,89 @@ return found; } +void +TimeValueLayer::getScaleExtents(View *v, float &min, float &max, bool &log) const +{ + min = 0.0; + max = 0.0; + log = false; + + if (m_verticalScale == AutoAlignScale) { + + if (!v->getValueExtents(m_model->getScaleUnits(), min, max, log)) { + 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); + } + + } else if (m_verticalScale == PlusMinusOneScale) { + + min = -1.0; + max = 1.0; + + } else { + + min = m_model->getValueMinimum(); + 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); + log = true; + } + } + + if (max == min) max = min + 1.0; +} + int TimeValueLayer::getYForValue(View *v, float val) const { float min = 0.0, max = 0.0; + bool logarithmic = false; int h = v->height(); - if (!v->getValueExtents(m_model->getScaleUnits(), min, max)) { - min = m_model->getValueMinimum(); - max = m_model->getValueMaximum(); + getScaleExtents(v, min, max, logarithmic); + +// std::cerr << "getYForValue(" << val << "): min " << min << ", max " +// << max << ", log " << logarithmic << std::endl; + + if (logarithmic) { + val = (val < 0.0) ? -log10(-val) : (val == 0.0) ? 0.0 : log10(val); } - if (max == min) max = min + 1.0; - -/*!!! - float min = m_model->getValueMinimum(); - float max = m_model->getValueMaximum(); - if (max == min) max = min + 1.0; - - int h = v->height(); - - if (m_verticalScale == FrequencyScale || m_verticalScale == LogScale) { - - if (m_verticalScale == FrequencyScale) { - // If we have a spectrogram layer on the same view as us, align - // ourselves with it... - for (int i = 0; i < v->getLayerCount(); ++i) { - SpectrogramLayer *spectrogram = dynamic_cast - (v->getLayer(i)); - if (spectrogram) { - return spectrogram->getYForFrequency(v, val); - } - } - } - - 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); - val = (val < 0.0) ? -log10(-val) : (val == 0.0) ? 0.0 : log10(val); - - } else if (m_verticalScale == PlusMinusOneScale) { - min = -1.0; - max = 1.0; - } -*/ - return int(h - ((val - min) * h) / (max - min)); } float TimeValueLayer::getValueForY(View *v, int y) const { - //!!! - - float min = m_model->getValueMinimum(); - float max = m_model->getValueMaximum(); - if (max == min) max = min + 1.0; - + float min = 0.0, max = 0.0; + bool logarithmic = false; int h = v->height(); - return min + (float(h - y) * float(max - min)) / h; + getScaleExtents(v, min, max, logarithmic); + + float val = min + (float(h - y) * float(max - min)) / h; + + if (logarithmic) { + val = pow(10, val); + } + + return val; } QColor -TimeValueLayer::getColourForValue(float val) const +TimeValueLayer::getColourForValue(View *v, float val) const { - float min = m_model->getValueMinimum(); - float max = m_model->getValueMaximum(); - if (max == min) max = min + 1.0; + float min, max; + bool log; + getScaleExtents(v, min, max, log); - if (m_verticalScale == FrequencyScale || 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); + if (log) { val = (val < 0.0) ? -log10(-val) : (val == 0.0) ? 0.0 : log10(val); - } else if (m_verticalScale == PlusMinusOneScale) { - min = -1.0; - max = 1.0; } int iv = ((val - min) / (max - min)) * 255.999; @@ -581,7 +606,7 @@ paint.setPen(m_colour); if (m_plotStyle == PlotSegmentation) { - paint.setBrush(getColourForValue(p.value)); + paint.setBrush(getColourForValue(v, p.value)); labelY = v->height(); } else if (m_plotStyle == PlotLines || m_plotStyle == PlotCurve) { @@ -744,7 +769,7 @@ paint.save(); for (int y = 0; y < boxh; ++y) { float val = ((boxh - y) * (max - min)) / boxh + min; - paint.setPen(getColourForValue(val)); + paint.setPen(getColourForValue(v, val)); paint.drawLine(boxx + 1, y + boxy + 1, boxx + boxw, y + boxy + 1); } paint.restore(); @@ -789,7 +814,7 @@ void TimeValueLayer::drawStart(View *v, QMouseEvent *e) { - std::cerr << "TimeValueLayer::drawStart(" << e->x() << "," << e->y() << ")" << std::endl; +// std::cerr << "TimeValueLayer::drawStart(" << e->x() << "," << e->y() << ")" << std::endl; if (!m_model) return; @@ -807,7 +832,7 @@ for (SparseTimeValueModel::PointList::iterator i = points.begin(); i != points.end(); ++i) { if (((i->frame / resolution) * resolution) != frame) { - std::cerr << "ignoring out-of-range frame at " << i->frame << std::endl; +// std::cerr << "ignoring out-of-range frame at " << i->frame << std::endl; continue; } m_editingPoint = *i; @@ -835,7 +860,7 @@ void TimeValueLayer::drawDrag(View *v, QMouseEvent *e) { - std::cerr << "TimeValueLayer::drawDrag(" << e->x() << "," << e->y() << ")" << std::endl; +// std::cerr << "TimeValueLayer::drawDrag(" << e->x() << "," << e->y() << ")" << std::endl; if (!m_model || !m_editing) return; @@ -848,7 +873,7 @@ SparseTimeValueModel::PointList points = getLocalPoints(v, e->x()); - std::cerr << points.size() << " points" << std::endl; +// std::cerr << points.size() << " points" << std::endl; bool havePoint = false; @@ -857,14 +882,14 @@ i != points.end(); ++i) { if (i->frame == m_editingPoint.frame && i->value == m_editingPoint.value) { - std::cerr << "ignoring current editing point at " << i->frame << ", " << i->value << std::endl; + // std::cerr << "ignoring current editing point at " << i->frame << ", " << i->value << std::endl; continue; } if (((i->frame / resolution) * resolution) != frame) { - std::cerr << "ignoring out-of-range frame at " << i->frame << std::endl; + // std::cerr << "ignoring out-of-range frame at " << i->frame << std::endl; continue; } - std::cerr << "adjusting to new point at " << i->frame << ", " << i->value << std::endl; + // std::cerr << "adjusting to new point at " << i->frame << ", " << i->value << std::endl; m_editingPoint = *i; m_originalPoint = m_editingPoint; m_editingCommand->deletePoint(m_editingPoint); @@ -887,7 +912,7 @@ void TimeValueLayer::drawEnd(View *v, QMouseEvent *e) { - std::cerr << "TimeValueLayer::drawEnd(" << e->x() << "," << e->y() << ")" << std::endl; +// std::cerr << "TimeValueLayer::drawEnd(" << e->x() << "," << e->y() << ")" << std::endl; if (!m_model || !m_editing) return; m_editingCommand->finish(); m_editingCommand = 0; @@ -897,7 +922,7 @@ void TimeValueLayer::editStart(View *v, QMouseEvent *e) { - std::cerr << "TimeValueLayer::editStart(" << e->x() << "," << e->y() << ")" << std::endl; +// std::cerr << "TimeValueLayer::editStart(" << e->x() << "," << e->y() << ")" << std::endl; if (!m_model) return; @@ -918,7 +943,7 @@ void TimeValueLayer::editDrag(View *v, QMouseEvent *e) { - std::cerr << "TimeValueLayer::editDrag(" << e->x() << "," << e->y() << ")" << std::endl; +// std::cerr << "TimeValueLayer::editDrag(" << e->x() << "," << e->y() << ")" << std::endl; if (!m_model || !m_editing) return; @@ -942,7 +967,7 @@ void TimeValueLayer::editEnd(View *v, QMouseEvent *e) { - std::cerr << "TimeValueLayer::editEnd(" << e->x() << "," << e->y() << ")" << std::endl; +// std::cerr << "TimeValueLayer::editEnd(" << e->x() << "," << e->y() << ")" << std::endl; if (!m_model || !m_editing) return; if (m_editingCommand) { diff -r 0db5e7492ce8 -r 0f36cdf407a6 layer/TimeValueLayer.h --- a/layer/TimeValueLayer.h Thu May 11 15:02:14 2006 +0000 +++ b/layer/TimeValueLayer.h Fri May 12 14:40:43 2006 +0000 @@ -88,10 +88,10 @@ PlotStyle getPlotStyle() const { return m_plotStyle; } enum VerticalScale { + AutoAlignScale, LinearScale, LogScale, - PlusMinusOneScale, - FrequencyScale + PlusMinusOneScale }; void setVerticalScale(VerticalScale scale); @@ -107,7 +107,10 @@ return m_plotStyle == PlotSegmentation && m_model->hasTextLabels(); } - virtual bool getValueExtents(float &min, float &max, QString &unit) const; + virtual bool getValueExtents(float &min, float &max, + bool &logarithmic, QString &unit) const; + + virtual bool getDisplayExtents(float &min, float &max) const; virtual QString toXmlString(QString indent = "", QString extraAttributes = "") const; @@ -115,10 +118,10 @@ void setProperties(const QXmlAttributes &attributes); protected: + void getScaleExtents(View *, float &min, float &max, bool &log) const; int getYForValue(View *, float value) const; float getValueForY(View *, int y) const; - - QColor getColourForValue(float value) const; + QColor getColourForValue(View *v, float value) const; SparseTimeValueModel::PointList getLocalPoints(View *v, int) const; diff -r 0db5e7492ce8 -r 0f36cdf407a6 layer/WaveformLayer.cpp --- a/layer/WaveformLayer.cpp Thu May 11 15:02:14 2006 +0000 +++ b/layer/WaveformLayer.cpp Fri May 12 14:40:43 2006 +0000 @@ -312,7 +312,7 @@ void WaveformLayer::setChannel(int channel) { - std::cerr << "WaveformLayer::setChannel(" << channel << ")" << std::endl; +// std::cerr << "WaveformLayer::setChannel(" << channel << ")" << std::endl; if (m_channel == channel) return; m_channel = channel; @@ -348,7 +348,8 @@ } bool -WaveformLayer::getValueExtents(float &min, float &max, QString &unit) const +WaveformLayer::getValueExtents(float &min, float &max, + bool &log, QString &unit) const { if (m_scale == LinearScale) { min = 0.0; diff -r 0db5e7492ce8 -r 0f36cdf407a6 layer/WaveformLayer.h --- a/layer/WaveformLayer.h Thu May 11 15:02:14 2006 +0000 +++ b/layer/WaveformLayer.h Fri May 12 14:40:43 2006 +0000 @@ -173,7 +173,8 @@ virtual int getCompletion() const; - virtual bool getValueExtents(float &min, float &max, QString &unit) const; + virtual bool getValueExtents(float &min, float &max, + bool &log, QString &unit) const; virtual QString toXmlString(QString indent = "", QString extraAttributes = "") const; diff -r 0db5e7492ce8 -r 0f36cdf407a6 widgets/ItemEditDialog.cpp --- a/widgets/ItemEditDialog.cpp Thu May 11 15:02:14 2006 +0000 +++ b/widgets/ItemEditDialog.cpp Fri May 12 14:40:43 2006 +0000 @@ -118,7 +118,7 @@ m_realDurationUSecsSpinBox->setMaximum(999999); m_realDurationUSecsSpinBox->setSuffix(tr(" usec")); m_realDurationUSecsSpinBox->setSingleStep(singleStep); - subgrid->addWidget(m_realDurationUSecsSpinBox, subrow, 3); + subgrid->addWidget(m_realDurationUSecsSpinBox, subrow, 2); connect(m_realDurationUSecsSpinBox, SIGNAL(valueChanged(int)), this, SLOT(realDurationUSecsChanged(int))); diff -r 0db5e7492ce8 -r 0f36cdf407a6 widgets/Pane.cpp --- a/widgets/Pane.cpp Thu May 11 15:02:14 2006 +0000 +++ b/widgets/Pane.cpp Fri May 12 14:40:43 2006 +0000 @@ -839,7 +839,7 @@ return; } - std::cerr << "mouseDoubleClickEvent" << std::endl; +// std::cerr << "mouseDoubleClickEvent" << std::endl; m_clickPos = e->pos(); m_clickedInRange = true; @@ -849,7 +849,8 @@ ViewManager::ToolMode mode = ViewManager::NavigateMode; if (m_manager) mode = m_manager->getToolMode(); - if (mode == ViewManager::EditMode) { + if (mode == ViewManager::NavigateMode || + mode == ViewManager::EditMode) { Layer *layer = getSelectedLayer(); if (layer && layer->isLayerEditable()) { @@ -1013,7 +1014,7 @@ Pane::toolModeChanged() { ViewManager::ToolMode mode = m_manager->getToolMode(); - std::cerr << "Pane::toolModeChanged(" << mode << ")" << std::endl; +// std::cerr << "Pane::toolModeChanged(" << mode << ")" << std::endl; switch (mode) {