Mercurial > hg > svgui
diff layer/TimeValueLayer.cpp @ 374:64e84e5efb76 spectrogram-cache-rejig
* Merge from trunk
author | Chris Cannam |
---|---|
date | Wed, 27 Feb 2008 11:59:42 +0000 |
parents | 4f4f38a11cd2 |
children |
line wrap: on
line diff
--- a/layer/TimeValueLayer.cpp Mon Nov 19 15:50:37 2007 +0000 +++ b/layer/TimeValueLayer.cpp Wed Feb 27 11:59:42 2008 +0000 @@ -23,6 +23,7 @@ #include "view/View.h" #include "data/model/SparseTimeValueModel.h" +#include "data/model/Labeller.h" #include "widgets/ItemEditDialog.h" #include "widgets/ListInputDialog.h" @@ -35,6 +36,8 @@ #include <QMouseEvent> #include <QRegExp> #include <QTextStream> +#include <QMessageBox> +#include <QInputDialog> #include <iostream> #include <cmath> @@ -538,6 +541,8 @@ int sampleRate = m_model->getSampleRate(); if (!sampleRate) return; + paint.setRenderHint(QPainter::Antialiasing, false); + // Profiler profiler("TimeValueLayer::paint", true); int x0 = rect.left(), x1 = rect.right(); @@ -599,6 +604,9 @@ if (m_plotStyle != PlotSegmentation) { textY = y - paint.fontMetrics().height() + paint.fontMetrics().ascent(); + if (textY < paint.fontMetrics().ascent() + 1) { + textY = paint.fontMetrics().ascent() + 1; + } } bool haveNext = false; @@ -940,6 +948,51 @@ } void +TimeValueLayer::eraseStart(View *v, QMouseEvent *e) +{ + if (!m_model) return; + + SparseTimeValueModel::PointList points = getLocalPoints(v, e->x()); + if (points.empty()) return; + + m_editingPoint = *points.begin(); + + if (m_editingCommand) { + m_editingCommand->finish(); + m_editingCommand = 0; + } + + m_editing = true; +} + +void +TimeValueLayer::eraseDrag(View *v, QMouseEvent *e) +{ +} + +void +TimeValueLayer::eraseEnd(View *v, QMouseEvent *e) +{ + if (!m_model || !m_editing) return; + + m_editing = false; + + SparseTimeValueModel::PointList points = getLocalPoints(v, e->x()); + if (points.empty()) return; + if (points.begin()->frame != m_editingPoint.frame || + points.begin()->value != m_editingPoint.value) return; + + m_editingCommand = new SparseTimeValueModel::EditCommand + (m_model, tr("Erase Point")); + + m_editingCommand->deletePoint(m_editingPoint); + + m_editingCommand->finish(); + m_editingCommand = 0; + m_editing = false; +} + +void TimeValueLayer::editStart(View *v, QMouseEvent *e) { // std::cerr << "TimeValueLayer::editStart(" << e->x() << "," << e->y() << ")" << std::endl; @@ -1136,7 +1189,7 @@ } void -TimeValueLayer::copy(Selection s, Clipboard &to) +TimeValueLayer::copy(View *v, Selection s, Clipboard &to) { if (!m_model) return; @@ -1147,45 +1200,55 @@ i != points.end(); ++i) { if (s.contains(i->frame)) { Clipboard::Point point(i->frame, i->value, i->label); + point.setReferenceFrame(alignToReference(v, i->frame)); to.addPoint(point); } } } bool -TimeValueLayer::paste(const Clipboard &from, int frameOffset, +TimeValueLayer::paste(View *v, const Clipboard &from, int frameOffset, bool interactive) { if (!m_model) return false; const Clipboard::PointList &points = from.getPoints(); + bool realign = false; + + if (clipboardHasDifferentAlignment(v, from)) { + + QMessageBox::StandardButton button = + QMessageBox::question(v, tr("Re-align pasted items?"), + tr("The items you are pasting came from a layer with different source material from this one. Do you want to re-align them in time, to match the source material for this layer?"), + QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, + QMessageBox::Yes); + + if (button == QMessageBox::Cancel) { + return false; + } + + if (button == QMessageBox::Yes) { + realign = true; + } + } + SparseTimeValueModel::EditCommand *command = new SparseTimeValueModel::EditCommand(m_model, tr("Paste")); - //!!! Replace all this with a use of Labeller - enum ValueAvailability { UnknownAvailability, NoValues, SomeValues, AllValues }; - enum ValueGeneration { - GenerateNone, - GenerateFromCounter, - GenerateFromFrameNumber, - GenerateFromRealTime, - GenerateFromRealTimeDifference, - GenerateFromTempo, - GenerateFromExistingNeighbour, - GenerateFromLabels - }; - ValueGeneration generation = GenerateNone; + Labeller::ValueType generation = Labeller::ValueNone; bool haveUsableLabels = false; bool haveExistingItems = !(m_model->isEmpty()); + Labeller labeller; + labeller.setSampleRate(m_model->getSampleRate()); if (interactive) { @@ -1232,38 +1295,18 @@ text = tr("Some of the items you are pasting do not have values.\nWhat values do you want to use for these items?"); } + Labeller::TypeNameMap names = labeller.getTypeNames(); + QStringList options; - std::vector<int> genopts; + std::vector<Labeller::ValueType> genopts; - options << tr("Zero for all items"); - genopts.push_back(int(GenerateNone)); - - options << tr("Whole numbers counting from 1"); - genopts.push_back(int(GenerateFromCounter)); - - options << tr("Item's audio sample frame number"); - genopts.push_back(int(GenerateFromFrameNumber)); - - options << tr("Item's time in seconds"); - genopts.push_back(int(GenerateFromRealTime)); - - options << tr("Duration from the item to the following item"); - genopts.push_back(int(GenerateFromRealTimeDifference)); - - options << tr("Tempo in bpm derived from the duration"); - genopts.push_back(int(GenerateFromTempo)); - - if (haveExistingItems) { - options << tr("Value of the nearest existing item"); - genopts.push_back(int(GenerateFromExistingNeighbour)); + for (Labeller::TypeNameMap::const_iterator i = names.begin(); + i != names.end(); ++i) { + if (i->first == Labeller::ValueNone) options << tr("Zero for all items"); + else options << i->second; + genopts.push_back(i->first); } - if (haveUsableLabels) { - options << tr("Value extracted from the item's label (where possible)"); - genopts.push_back(int(GenerateFromLabels)); - } - - static int prevSelection = 0; bool ok = false; @@ -1273,32 +1316,54 @@ if (!ok) return false; int selection = 0; - generation = GenerateNone; + generation = Labeller::ValueNone; for (QStringList::const_iterator i = options.begin(); i != options.end(); ++i) { if (selected == *i) { - generation = ValueGeneration(genopts[selection]); + generation = genopts[selection]; break; } ++selection; } + + labeller.setType(generation); + + if (generation == Labeller::ValueFromCyclicalCounter || + generation == Labeller::ValueFromTwoLevelCounter) { + int cycleSize = QInputDialog::getInteger + (0, tr("Select cycle size"), + tr("Cycle size:"), 4, 2, 16, 1); + labeller.setCounterCycleSize(cycleSize); + } prevSelection = selection; } } - int counter = 1; - float prevBpm = 120.f; + SparseTimeValueModel::Point prevPoint(0); for (Clipboard::PointList::const_iterator i = points.begin(); i != points.end(); ++i) { if (!i->haveFrame()) continue; + size_t frame = 0; - if (frameOffset > 0 || -frameOffset < i->getFrame()) { - frame = i->getFrame() + frameOffset; + + if (!realign) { + + frame = i->getFrame(); + + } else { + + if (i->haveReferenceFrame()) { + frame = i->getReferenceFrame(); + frame = alignFromReference(v, frame); + } else { + frame = i->getFrame(); + } } + SparseTimeValueModel::Point newPoint(frame); if (i->haveLabel()) { @@ -1307,81 +1372,33 @@ newPoint.label = QString("%1").arg(i->getValue()); } + bool usePrev = false; + SparseTimeValueModel::Point formerPrevPoint = prevPoint; + if (i->haveValue()) { newPoint.value = i->getValue(); } else { - - switch (generation) { - - case GenerateNone: - newPoint.value = 0; - break; - - case GenerateFromCounter: - newPoint.value = counter; - break; - - case GenerateFromFrameNumber: - newPoint.value = frame; - break; - - case GenerateFromRealTime: - newPoint.value = float(frame) / float(m_model->getSampleRate()); - break; - - case GenerateFromRealTimeDifference: - case GenerateFromTempo: - { - size_t nextFrame = frame; - Clipboard::PointList::const_iterator j = i; - for (; j != points.end(); ++j) { - if (!j->haveFrame()) continue; - if (j != i) break; - } - if (j != points.end()) { - nextFrame = j->getFrame(); - } - if (generation == GenerateFromRealTimeDifference) { - newPoint.value = float(nextFrame - frame) / - float(m_model->getSampleRate()); - } else { - float bpm = prevBpm; - if (nextFrame > frame) { - bpm = (60.f * m_model->getSampleRate()) / - (nextFrame - frame); - } - newPoint.value = bpm; - prevBpm = bpm; - } - break; - } - - case GenerateFromExistingNeighbour: - { - SparseTimeValueModel::PointList points = - m_model->getPoints(frame); - if (points.empty()) points = m_model->getPreviousPoints(frame); - if (points.empty()) points = m_model->getNextPoints(frame); - if (points.empty()) { - newPoint.value = 0.f; - } else { - newPoint.value = points.begin()->value; - } - } - - case GenerateFromLabels: - if (i->haveLabel()) { - // more forgiving than QString::toFloat() - newPoint.value = atof(i->getLabel().toLocal8Bit()); - } else { - newPoint.value = 0.f; - } +// std::cerr << "Setting value on point at " << newPoint.frame << " from labeller"; +// if (i == points.begin()) { +// std::cerr << ", no prev point" << std::endl; +// } else { +// std::cerr << ", prev point is at " << prevPoint.frame << std::endl; +// } + labeller.setValue<SparseTimeValueModel::Point> + (newPoint, (i == points.begin()) ? 0 : &prevPoint); +// std::cerr << "New point value = " << newPoint.value << std::endl; + if (labeller.actingOnPrevPoint() && i != points.begin()) { + usePrev = true; } } - + + if (usePrev) { + command->deletePoint(formerPrevPoint); + command->addPoint(prevPoint); + } + + prevPoint = newPoint; command->addPoint(newPoint); - - ++counter; } command->finish();