Mercurial > hg > svgui
changeset 273:e954c00cbe55
* proper (though ugly) handling of y coord for measure rects in scrollable layers
author | Chris Cannam |
---|---|
date | Fri, 29 Jun 2007 16:50:59 +0000 |
parents | 87e4c880b4c8 |
children | b9380f679f70 |
files | layer/Layer.cpp layer/Layer.h layer/SpectrogramLayer.cpp layer/SpectrogramLayer.h |
diffstat | 4 files changed, 90 insertions(+), 22 deletions(-) [+] |
line wrap: on
line diff
--- a/layer/Layer.cpp Fri Jun 29 13:58:08 2007 +0000 +++ b/layer/Layer.cpp Fri Jun 29 16:50:59 2007 +0000 @@ -169,7 +169,7 @@ } s += QString("startY=\"%1\" endY=\"%2\"/>\n") - .arg(pixrect.y()).arg(pixrect.y() + pixrect.height()); + .arg(startY).arg(endY); return s; } @@ -179,7 +179,7 @@ { MeasureRect rect; QString fs = attributes.value("startFrame"); - int x0 = 0, y0 = 0, x1 = 0, y1 = 0; + int x0 = 0, x1 = 0; if (fs != "") { rect.startFrame = fs.toLong(); rect.endFrame = attributes.value("endFrame").toLong(); @@ -189,9 +189,9 @@ x1 = attributes.value("endX").toInt(); rect.haveFrames = false; } - y0 = attributes.value("startY").toInt(); - y1 = attributes.value("endY").toInt(); - rect.pixrect = QRect(x0, y0, x1 - x0, y1 - y0); + rect.startY = attributes.value("startY").toDouble(); + rect.endY = attributes.value("endY").toDouble(); + rect.pixrect = QRect(x0, 0, x1 - x0, 0); addMeasureRectToSet(rect); } @@ -224,6 +224,7 @@ } else { m_draggingRect.haveFrames = false; } + setMeasureRectYCoord(v, m_draggingRect, true, e->y()); m_haveDraggingRect = true; } @@ -238,6 +239,8 @@ e->y() - m_draggingRect.pixrect.y()) .normalized(); + setMeasureRectYCoord(v, m_draggingRect, false, e->y()); + if (hasTimeXAxis()) { m_draggingRect.endFrame = v->getFrameForX(e->x()); } @@ -259,7 +262,7 @@ Layer::paintMeasurementRects(View *v, QPainter &paint, bool showFocus, QPoint focusPoint) const { - updateMeasurementPixrects(v); + updateMeasurePixrects(v); MeasureRectSet::const_iterator focusRectItr = m_measureRects.end(); @@ -281,7 +284,7 @@ bool Layer::nearestMeasurementRectChanged(View *v, QPoint prev, QPoint now) const { - updateMeasurementPixrects(v); + updateMeasurePixrects(v); MeasureRectSet::const_iterator i0 = findFocusedMeasureRect(prev); MeasureRectSet::const_iterator i1 = findFocusedMeasureRect(now); @@ -290,7 +293,7 @@ } void -Layer::updateMeasurementPixrects(View *v) const +Layer::updateMeasurePixrects(View *v) const { long sf = v->getStartFrame(); long ef = v->getEndFrame(); @@ -298,24 +301,54 @@ for (MeasureRectSet::const_iterator i = m_measureRects.begin(); i != m_measureRects.end(); ++i) { - if (!i->haveFrames) continue; + // This logic depends on the fact that if one measure rect in + // a layer has frame values, they all will. That is in fact + // the case, because haveFrames is based on whether the layer + // hasTimeXAxis() or not. Measure rect ordering in the rect + // set wouldn't work correctly either, if haveFrames could + // vary. - if (i->startFrame >= ef) break; - if (i->endFrame <= sf) continue; + if (i->haveFrames) { + if (i->startFrame >= ef) break; + if (i->endFrame <= sf) continue; + } - int x0 = -1; - int x1 = v->width() + 1; - - if (i->startFrame >= v->getStartFrame()) { - x0 = v->getXForFrame(i->startFrame); - } - if (i->endFrame <= long(v->getEndFrame())) { - x1 = v->getXForFrame(i->endFrame); + int x0 = i->pixrect.x(); + int x1 = x0 + i->pixrect.width(); + + if (i->haveFrames) { + if (i->startFrame >= v->getStartFrame()) { + x0 = v->getXForFrame(i->startFrame); + } + if (i->endFrame <= long(v->getEndFrame())) { + x1 = v->getXForFrame(i->endFrame); + } } - QRect pr = QRect(x0, i->pixrect.y(), x1 - x0, i->pixrect.height()); + i->pixrect = QRect(x0, i->pixrect.y(), x1 - x0, i->pixrect.height()); + + updateMeasureRectYCoords(v, *i); - i->pixrect = pr; + i->pixrect = i->pixrect.normalized(); + } +} + +void +Layer::updateMeasureRectYCoords(View *v, const MeasureRect &r) const +{ + int y0 = lrint(r.startY * v->height()); + int y1 = lrint(r.endY * v->height()); + r.pixrect = QRect(r.pixrect.x(), y0, r.pixrect.width(), y1 - y0); +} + +void +Layer::setMeasureRectYCoord(View *v, MeasureRect &r, bool start, int y) const +{ + if (start) { + r.startY = double(y) / double(v->height()); + r.endY = r.startY; + } else { + r.endY = double(y) / double(v->height()); } }
--- a/layer/Layer.h Fri Jun 29 13:58:08 2007 +0000 +++ b/layer/Layer.h Fri Jun 29 16:50:59 2007 +0000 @@ -429,6 +429,8 @@ bool haveFrames; long startFrame; // only valid if haveFrames long endFrame; // ditto + double startY; + double endY; bool operator<(const MeasureRect &mr) const; QString toXmlString(QString indent) const; @@ -467,7 +469,10 @@ // Note that pixrects are only correct for a single view. // So we should update them at the start of the paint procedure // (painting is single threaded) and only use them after that. - void updateMeasurementPixrects(View *v) const; + void updateMeasurePixrects(View *v) const; + + virtual void updateMeasureRectYCoords(View *v, const MeasureRect &r) const; + virtual void setMeasureRectYCoord(View *v, MeasureRect &r, bool start, int y) const; // This assumes updateMeasurementPixrects has been called MeasureRectSet::const_iterator findFocusedMeasureRect(QPoint) const;
--- a/layer/SpectrogramLayer.cpp Fri Jun 29 13:58:08 2007 +0000 +++ b/layer/SpectrogramLayer.cpp Fri Jun 29 16:50:59 2007 +0000 @@ -3066,6 +3066,33 @@ return new SpectrogramRangeMapper(m_model->getSampleRate(), m_fftSize); } +void +SpectrogramLayer::updateMeasureRectYCoords(View *v, const MeasureRect &r) const +{ + int y0 = 0; + if (r.startY > 0.0) y0 = getYForFrequency(v, r.startY); + + int y1 = y0; + if (r.endY > 0.0) y1 = getYForFrequency(v, r.endY); + +// std::cerr << "SpectrogramLayer::updateMeasureRectYCoords: start " << r.startY << " -> " << y0 << ", end " << r.endY << " -> " << y1 << std::endl; + + r.pixrect = QRect(r.pixrect.x(), y0, r.pixrect.width(), y1 - y0); +} + +void +SpectrogramLayer::setMeasureRectYCoord(View *v, MeasureRect &r, bool start, int y) const +{ + if (start) { + r.startY = getFrequencyForY(v, y); + r.endY = r.startY; + } else { + r.endY = getFrequencyForY(v, y); + } +// std::cerr << "SpectrogramLayer::setMeasureRectYCoord: start " << r.startY << " <- " << y << ", end " << r.endY << " <- " << y << std::endl; + +} + QString SpectrogramLayer::toXmlString(QString indent, QString extraAttributes) const {
--- a/layer/SpectrogramLayer.h Fri Jun 29 13:58:08 2007 +0000 +++ b/layer/SpectrogramLayer.h Fri Jun 29 16:50:59 2007 +0000 @@ -401,6 +401,9 @@ mutable std::vector<MagnitudeRange> m_columnMags; void invalidateMagnitudes(); bool updateViewMagnitudes(View *v) const; + + virtual void updateMeasureRectYCoords(View *v, const MeasureRect &r) const; + virtual void setMeasureRectYCoord(View *v, MeasureRect &r, bool start, int y) const; }; #endif