# HG changeset patch # User Chris Cannam # Date 1571307174 -3600 # Node ID e6362cf5ff1dde2c28b691f769fead77f74feae1 # Parent ec837d223bd9985c10722208b344a9f56086c07d Pass a y-coord, optionally, to Layer::snapToFeatureFrame. This is necessary for BoxLayer which needs to coordinate its snaps with the box it is highlighting for editing. Then in BoxLayer, merge getPointToDrag and getLocalPoints into a single getLocalPoint and use this throughout. diff -r ec837d223bd9 -r e6362cf5ff1d layer/BoxLayer.cpp --- a/layer/BoxLayer.cpp Thu Oct 17 10:26:21 2019 +0100 +++ b/layer/BoxLayer.cpp Thu Oct 17 11:12:54 2019 +0100 @@ -239,36 +239,12 @@ } } -EventVector -BoxLayer::getLocalPoints(LayerGeometryProvider *v, int x) const +bool +BoxLayer::getLocalPoint(LayerGeometryProvider *v, int x, int y, + Event &point) const { auto model = ModelById::getAs(m_model); - if (!model) return EventVector(); - - sv_frame_t frame = v->getFrameForX(x); - - EventVector local = model->getEventsCovering(frame); - if (!local.empty()) return local; - - int fuzz = ViewManager::scalePixelSize(2); - sv_frame_t start = v->getFrameForX(x - fuzz); - sv_frame_t end = v->getFrameForX(x + fuzz); - - local = model->getEventsStartingWithin(frame, end - frame); - if (!local.empty()) return local; - - local = model->getEventsSpanning(start, frame - start); - if (!local.empty()) return local; - - return {}; -} - -bool -BoxLayer::getPointToDrag(LayerGeometryProvider *v, int x, int y, - Event &point) const -{ - auto model = ModelById::getAs(m_model); - if (!model) return false; + if (!model || !model->isReady()) return false; sv_frame_t frame = v->getFrameForX(x); @@ -308,9 +284,10 @@ } else { int nearestDistance = -1; for (const auto &p: onPoints) { + const auto r = getRange(p); int distance = std::min - (getYForValue(v, p.getValue()) - y, - getYForValue(v, p.getValue() + fabsf(p.getLevel())) - y); + (getYForValue(v, r.first) - y, + getYForValue(v, r.second) - y); if (distance < 0) distance = -distance; if (nearestDistance == -1 || distance < nearestDistance) { nearestDistance = distance; @@ -343,14 +320,12 @@ BoxLayer::getFeatureDescription(LayerGeometryProvider *v, QPoint &pos) const { - int x = pos.x(); - auto model = ModelById::getAs(m_model); if (!model || !model->getSampleRate()) return ""; - - EventVector points = getLocalPoints(v, x); - - if (points.empty()) { + + Event box; + + if (!getLocalPoint(v, pos.x(), pos.y(), box)) { if (!model->isReady()) { return tr("In progress"); } else { @@ -358,32 +333,17 @@ } } - Event box; - EventVector::iterator i; - - for (i = points.begin(); i != points.end(); ++i) { - - int y0 = getYForValue(v, i->getValue()); - int y1 = getYForValue(v, i->getValue() + fabsf(i->getLevel())); - - if (pos.y() >= y0 && pos.y() <= y1) { - box = *i; - break; - } - } - - if (i == points.end()) return tr("No local points"); - RealTime rt = RealTime::frame2RealTime(box.getFrame(), model->getSampleRate()); RealTime rd = RealTime::frame2RealTime(box.getDuration(), model->getSampleRate()); QString rangeText; - + auto r = getRange(box); + rangeText = tr("%1 %2 - %3 %4") - .arg(box.getValue()).arg(getScaleUnits()) - .arg(box.getValue() + fabsf(box.getLevel())).arg(getScaleUnits()); + .arg(r.first).arg(getScaleUnits()) + .arg(r.second).arg(getScaleUnits()); QString text; @@ -409,11 +369,12 @@ BoxLayer::snapToFeatureFrame(LayerGeometryProvider *v, sv_frame_t &frame, int &resolution, - SnapType snap) const + SnapType snap, + int ycoord) const { auto model = ModelById::getAs(m_model); if (!model) { - return Layer::snapToFeatureFrame(v, frame, resolution, snap); + return Layer::snapToFeatureFrame(v, frame, resolution, snap, ycoord); } // SnapLeft / SnapRight: return frame of nearest feature in that @@ -425,57 +386,52 @@ resolution = model->getResolution(); + Event containing; + + if (getLocalPoint(v, v->getXForFrame(frame), ycoord, containing)) { + + switch (snap) { + + case SnapLeft: + case SnapNeighbouring: + frame = containing.getFrame(); + return true; + + case SnapRight: + frame = containing.getFrame() + containing.getDuration(); + return true; + } + } + if (snap == SnapNeighbouring) { - EventVector points = getLocalPoints(v, v->getXForFrame(frame)); - if (points.empty()) return false; - frame = points.begin()->getFrame(); - return true; + return false; } - // Normally we snap to the start frame of whichever event we - // find. However here, for SnapRight only, if the end frame of - // whichever event we would have snapped to had we been snapping - // left is closer than the start frame of the next event to the - // right, then we snap to that frame instead. Clear? + // We aren't actually contained (in time) by any single event, so + // seek the next one in the relevant direction + + Event e; - Event left; - bool haveLeft = false; - if (model->getNearestEventMatching - (frame, [](Event) { return true; }, EventSeries::Backward, left)) { - haveLeft = true; - } + if (snap == SnapLeft) { + if (model->getNearestEventMatching + (frame, [](Event) { return true; }, EventSeries::Backward, e)) { - if (snap == SnapLeft) { - frame = left.getFrame(); - return haveLeft; - } - - Event right; - bool haveRight = false; - if (model->getNearestEventMatching - (frame, [](Event) { return true; }, EventSeries::Forward, right)) { - haveRight = true; - } - - if (haveLeft) { - sv_frame_t leftEnd = left.getFrame() + left.getDuration(); - if (leftEnd > frame) { - if (haveRight) { - if (leftEnd - frame < right.getFrame() - frame) { - frame = leftEnd; - } else { - frame = right.getFrame(); - } + if (e.getFrame() + e.getDuration() < frame) { + frame = e.getFrame() + e.getDuration(); } else { - frame = leftEnd; + frame = e.getFrame(); } return true; } } + + if (snap == SnapRight) { + if (model->getNearestEventMatching + (frame, [](Event) { return true; }, EventSeries::Forward, e)) { - if (haveRight) { - frame = right.getFrame(); - return true; + frame = e.getFrame(); + return true; + } } return false; @@ -607,8 +563,8 @@ bool shouldIlluminate = false; if (v->shouldIlluminateLocalFeatures(this, localPos)) { - shouldIlluminate = getPointToDrag(v, localPos.x(), localPos.y(), - illuminatePoint); + shouldIlluminate = getLocalPoint(v, localPos.x(), localPos.y(), + illuminatePoint); } paint.save(); @@ -620,11 +576,12 @@ i != points.end(); ++i) { const Event &p(*i); + const auto r = getRange(p); int x = v->getXForFrame(p.getFrame()); int w = v->getXForFrame(p.getFrame() + p.getDuration()) - x; - int y = getYForValue(v, p.getValue()); - int h = getYForValue(v, p.getValue() + fabsf(p.getLevel())) - y; + int y = getYForValue(v, r.first); + int h = getYForValue(v, r.second) - y; int ex = x + w; int gap = v->scalePixelSize(2); @@ -655,11 +612,11 @@ if (abs(h) > 2 * fm.height()) { QString y0label = QString("%1 %2") - .arg(p.getValue()) + .arg(r.first) .arg(getScaleUnits()); QString y1label = QString("%1 %2") - .arg(p.getValue() + fabsf(p.getLevel())) + .arg(r.second) .arg(getScaleUnits()); PaintAssistant::drawVisibleText @@ -677,9 +634,9 @@ } else { QString ylabel = QString("%1 %2 - %3 %4") - .arg(p.getValue()) + .arg(r.first) .arg(getScaleUnits()) - .arg(p.getValue() + fabsf(p.getLevel())) + .arg(r.second) .arg(getScaleUnits()); PaintAssistant::drawVisibleText @@ -880,7 +837,7 @@ auto model = ModelById::getAs(m_model); if (!model) return; - if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return; + if (!getLocalPoint(v, e->x(), e->y(), m_editingPoint)) return; if (m_editingCommand) { finish(m_editingCommand); @@ -904,7 +861,7 @@ m_editing = false; Event p(0); - if (!getPointToDrag(v, e->x(), e->y(), p)) return; + if (!getLocalPoint(v, e->x(), e->y(), p)) return; if (p.getFrame() != m_editingPoint.getFrame() || p.getValue() != m_editingPoint.getValue()) return; @@ -924,7 +881,7 @@ auto model = ModelById::getAs(m_model); if (!model) return; - if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) { + if (!getLocalPoint(v, e->x(), e->y(), m_editingPoint)) { return; } @@ -1008,7 +965,7 @@ if (!model) return false; Event region(0); - if (!getPointToDrag(v, e->x(), e->y(), region)) return false; + if (!getLocalPoint(v, e->x(), e->y(), region)) return false; ItemEditDialog::LabelOptions labelOptions; labelOptions.valueLabel = tr("Minimum Value"); diff -r ec837d223bd9 -r e6362cf5ff1d layer/BoxLayer.h --- a/layer/BoxLayer.h Thu Oct 17 10:26:21 2019 +0100 +++ b/layer/BoxLayer.h Thu Oct 17 11:12:54 2019 +0100 @@ -46,7 +46,7 @@ bool snapToFeatureFrame(LayerGeometryProvider *v, sv_frame_t &frame, int &resolution, - SnapType snap) const override; + SnapType snap, int ycoord) const override; void drawStart(LayerGeometryProvider *v, QMouseEvent *) override; void drawDrag(LayerGeometryProvider *v, QMouseEvent *) override; @@ -118,9 +118,12 @@ protected: void getScaleExtents(LayerGeometryProvider *, double &min, double &max, bool &log) const; - EventVector getLocalPoints(LayerGeometryProvider *v, int x) const; - - bool getPointToDrag(LayerGeometryProvider *v, int x, int y, Event &) const; + // Return the event that "most closely contains" the given + // coordinates, if any; or the closest event that spans the given + // x coordinate in the time axis; or false otherwise. This + // subsumes the uses of both getPointToDrag and getLocalPoints in + // some other layer implementations. + bool getLocalPoint(LayerGeometryProvider *v, int x, int y, Event &) const; ModelId m_model; bool m_editing; diff -r ec837d223bd9 -r e6362cf5ff1d layer/Colour3DPlotLayer.cpp --- a/layer/Colour3DPlotLayer.cpp Thu Oct 17 10:26:21 2019 +0100 +++ b/layer/Colour3DPlotLayer.cpp Thu Oct 17 11:12:54 2019 +0100 @@ -1215,13 +1215,15 @@ } bool -Colour3DPlotLayer::snapToFeatureFrame(LayerGeometryProvider *v, sv_frame_t &frame, +Colour3DPlotLayer::snapToFeatureFrame(LayerGeometryProvider *v, + sv_frame_t &frame, int &resolution, - SnapType snap) const + SnapType snap, + int ycoord) const { auto model = ModelById::getAs(m_model); if (!model) { - return Layer::snapToFeatureFrame(v, frame, resolution, snap); + return Layer::snapToFeatureFrame(v, frame, resolution, snap, ycoord); } resolution = model->getResolution(); diff -r ec837d223bd9 -r e6362cf5ff1d layer/Colour3DPlotLayer.h --- a/layer/Colour3DPlotLayer.h Thu Oct 17 10:26:21 2019 +0100 +++ b/layer/Colour3DPlotLayer.h Thu Oct 17 11:12:54 2019 +0100 @@ -64,7 +64,7 @@ bool snapToFeatureFrame(LayerGeometryProvider *v, sv_frame_t &frame, int &resolution, - SnapType snap) const override; + SnapType snap, int ycoord) const override; void setLayerDormant(const LayerGeometryProvider *v, bool dormant) override; diff -r ec837d223bd9 -r e6362cf5ff1d layer/FlexiNoteLayer.cpp --- a/layer/FlexiNoteLayer.cpp Thu Oct 17 10:26:21 2019 +0100 +++ b/layer/FlexiNoteLayer.cpp Thu Oct 17 11:12:54 2019 +0100 @@ -586,11 +586,11 @@ bool FlexiNoteLayer::snapToFeatureFrame(LayerGeometryProvider *v, sv_frame_t &frame, int &resolution, - SnapType snap) const + SnapType snap, int ycoord) const { auto model = ModelById::getAs(m_model); if (!model) { - return Layer::snapToFeatureFrame(v, frame, resolution, snap); + return Layer::snapToFeatureFrame(v, frame, resolution, snap, ycoord); } resolution = model->getResolution(); diff -r ec837d223bd9 -r e6362cf5ff1d layer/FlexiNoteLayer.h --- a/layer/FlexiNoteLayer.h Thu Oct 17 10:26:21 2019 +0100 +++ b/layer/FlexiNoteLayer.h Thu Oct 17 11:12:54 2019 +0100 @@ -44,8 +44,8 @@ QString getFeatureDescription(LayerGeometryProvider *v, QPoint &) const override; bool snapToFeatureFrame(LayerGeometryProvider *v, sv_frame_t &frame, - int &resolution, - SnapType snap) const override; + int &resolution, + SnapType snap, int ycoord) const override; void drawStart(LayerGeometryProvider *v, QMouseEvent *) override; void drawDrag(LayerGeometryProvider *v, QMouseEvent *) override; diff -r ec837d223bd9 -r e6362cf5ff1d layer/ImageLayer.cpp --- a/layer/ImageLayer.cpp Thu Oct 17 10:26:21 2019 +0100 +++ b/layer/ImageLayer.cpp Thu Oct 17 11:12:54 2019 +0100 @@ -222,11 +222,11 @@ bool ImageLayer::snapToFeatureFrame(LayerGeometryProvider *v, sv_frame_t &frame, int &resolution, - SnapType snap) const + SnapType snap, int ycoord) const { auto model = ModelById::getAs(m_model); if (!model) { - return Layer::snapToFeatureFrame(v, frame, resolution, snap); + return Layer::snapToFeatureFrame(v, frame, resolution, snap, ycoord); } resolution = model->getResolution(); diff -r ec837d223bd9 -r e6362cf5ff1d layer/ImageLayer.h --- a/layer/ImageLayer.h Thu Oct 17 10:26:21 2019 +0100 +++ b/layer/ImageLayer.h Thu Oct 17 11:12:54 2019 +0100 @@ -44,7 +44,7 @@ bool snapToFeatureFrame(LayerGeometryProvider *v, sv_frame_t &frame, int &resolution, - SnapType snap) const override; + SnapType snap, int ycoord) const override; void drawStart(LayerGeometryProvider *v, QMouseEvent *) override; void drawDrag(LayerGeometryProvider *v, QMouseEvent *) override; diff -r ec837d223bd9 -r e6362cf5ff1d layer/Layer.h --- a/layer/Layer.h Thu Oct 17 10:26:21 2019 +0100 +++ b/layer/Layer.h Thu Oct 17 11:12:54 2019 +0100 @@ -185,6 +185,13 @@ * would be used in an editing operation through calls to * editStart etc. * + * If ycoord is non-negative, it contains the y coordinate at + * which the interaction that prompts this snap is taking place + * (e.g. of the mouse press used for a selection action). Layers + * that have objects at multiple different heights may choose to + * use this information. If the current action has no particular y + * coordinate associated with it, ycoord will be passed as -1. + * * Return true if a suitable feature was found and frame adjusted * accordingly. Return false if no suitable feature was available * (and leave frame unmodified). If returning true, also return @@ -193,7 +200,8 @@ virtual bool snapToFeatureFrame(LayerGeometryProvider * /* v */, sv_frame_t & /* frame */, int &resolution, - SnapType /* snap */) const { + SnapType /* snap */, + int /* ycoord */) const { resolution = 1; return false; } diff -r ec837d223bd9 -r e6362cf5ff1d layer/NoteLayer.cpp --- a/layer/NoteLayer.cpp Thu Oct 17 10:26:21 2019 +0100 +++ b/layer/NoteLayer.cpp Thu Oct 17 11:12:54 2019 +0100 @@ -547,11 +547,11 @@ bool NoteLayer::snapToFeatureFrame(LayerGeometryProvider *v, sv_frame_t &frame, int &resolution, - SnapType snap) const + SnapType snap, int ycoord) const { auto model = ModelById::getAs(m_model); if (!model) { - return Layer::snapToFeatureFrame(v, frame, resolution, snap); + return Layer::snapToFeatureFrame(v, frame, resolution, snap, ycoord); } // SnapLeft / SnapRight: return frame of nearest feature in that diff -r ec837d223bd9 -r e6362cf5ff1d layer/NoteLayer.h --- a/layer/NoteLayer.h Thu Oct 17 10:26:21 2019 +0100 +++ b/layer/NoteLayer.h Thu Oct 17 11:12:54 2019 +0100 @@ -43,8 +43,8 @@ QString getFeatureDescription(LayerGeometryProvider *v, QPoint &) const override; bool snapToFeatureFrame(LayerGeometryProvider *v, sv_frame_t &frame, - int &resolution, - SnapType snap) const override; + int &resolution, + SnapType snap, int ycoord) const override; void drawStart(LayerGeometryProvider *v, QMouseEvent *) override; void drawDrag(LayerGeometryProvider *v, QMouseEvent *) override; diff -r ec837d223bd9 -r e6362cf5ff1d layer/RegionLayer.cpp --- a/layer/RegionLayer.cpp Thu Oct 17 10:26:21 2019 +0100 +++ b/layer/RegionLayer.cpp Thu Oct 17 11:12:54 2019 +0100 @@ -466,11 +466,11 @@ bool RegionLayer::snapToFeatureFrame(LayerGeometryProvider *v, sv_frame_t &frame, int &resolution, - SnapType snap) const + SnapType snap, int ycoord) const { auto model = ModelById::getAs(m_model); if (!model) { - return Layer::snapToFeatureFrame(v, frame, resolution, snap); + return Layer::snapToFeatureFrame(v, frame, resolution, snap, ycoord); } // SnapLeft / SnapRight: return frame of nearest feature in that diff -r ec837d223bd9 -r e6362cf5ff1d layer/RegionLayer.h --- a/layer/RegionLayer.h Thu Oct 17 10:26:21 2019 +0100 +++ b/layer/RegionLayer.h Thu Oct 17 11:12:54 2019 +0100 @@ -49,7 +49,7 @@ bool snapToFeatureFrame(LayerGeometryProvider *v, sv_frame_t &frame, int &resolution, - SnapType snap) const override; + SnapType snap, int ycoord) const override; bool snapToSimilarFeature(LayerGeometryProvider *v, sv_frame_t &frame, int &resolution, SnapType snap) const override; diff -r ec837d223bd9 -r e6362cf5ff1d layer/SpectrogramLayer.cpp --- a/layer/SpectrogramLayer.cpp Thu Oct 17 10:26:21 2019 +0100 +++ b/layer/SpectrogramLayer.cpp Thu Oct 17 11:12:54 2019 +0100 @@ -1844,7 +1844,7 @@ SpectrogramLayer::snapToFeatureFrame(LayerGeometryProvider *, sv_frame_t &frame, int &resolution, - SnapType snap) const + SnapType snap, int) const { resolution = getWindowIncrement(); sv_frame_t left = (frame / resolution) * resolution; diff -r ec837d223bd9 -r e6362cf5ff1d layer/SpectrogramLayer.h --- a/layer/SpectrogramLayer.h Thu Oct 17 10:26:21 2019 +0100 +++ b/layer/SpectrogramLayer.h Thu Oct 17 11:12:54 2019 +0100 @@ -78,8 +78,8 @@ QString getFeatureDescription(LayerGeometryProvider *v, QPoint &) const override; bool snapToFeatureFrame(LayerGeometryProvider *v, sv_frame_t &frame, - int &resolution, - SnapType snap) const override; + int &resolution, + SnapType snap, int ycoord) const override; void measureDoubleClick(LayerGeometryProvider *, QMouseEvent *) override; diff -r ec837d223bd9 -r e6362cf5ff1d layer/TextLayer.cpp --- a/layer/TextLayer.cpp Thu Oct 17 10:26:21 2019 +0100 +++ b/layer/TextLayer.cpp Thu Oct 17 11:12:54 2019 +0100 @@ -238,11 +238,11 @@ bool TextLayer::snapToFeatureFrame(LayerGeometryProvider *v, sv_frame_t &frame, int &resolution, - SnapType snap) const + SnapType snap, int ycoord) const { auto model = ModelById::getAs(m_model); if (!model) { - return Layer::snapToFeatureFrame(v, frame, resolution, snap); + return Layer::snapToFeatureFrame(v, frame, resolution, snap, ycoord); } // SnapLeft / SnapRight: return frame of nearest feature in that diff -r ec837d223bd9 -r e6362cf5ff1d layer/TextLayer.h --- a/layer/TextLayer.h Thu Oct 17 10:26:21 2019 +0100 +++ b/layer/TextLayer.h Thu Oct 17 11:12:54 2019 +0100 @@ -37,8 +37,8 @@ QString getFeatureDescription(LayerGeometryProvider *v, QPoint &) const override; bool snapToFeatureFrame(LayerGeometryProvider *v, sv_frame_t &frame, - int &resolution, - SnapType snap) const override; + int &resolution, + SnapType snap, int ycoord) const override; void drawStart(LayerGeometryProvider *v, QMouseEvent *) override; void drawDrag(LayerGeometryProvider *v, QMouseEvent *) override; diff -r ec837d223bd9 -r e6362cf5ff1d layer/TimeInstantLayer.cpp --- a/layer/TimeInstantLayer.cpp Thu Oct 17 10:26:21 2019 +0100 +++ b/layer/TimeInstantLayer.cpp Thu Oct 17 11:12:54 2019 +0100 @@ -277,11 +277,11 @@ bool TimeInstantLayer::snapToFeatureFrame(LayerGeometryProvider *v, sv_frame_t &frame, int &resolution, - SnapType snap) const + SnapType snap, int ycoord) const { auto model = ModelById::getAs(m_model); if (!model) { - return Layer::snapToFeatureFrame(v, frame, resolution, snap); + return Layer::snapToFeatureFrame(v, frame, resolution, snap, ycoord); } // SnapLeft / SnapRight: return frame of nearest feature in that diff -r ec837d223bd9 -r e6362cf5ff1d layer/TimeInstantLayer.h --- a/layer/TimeInstantLayer.h Thu Oct 17 10:26:21 2019 +0100 +++ b/layer/TimeInstantLayer.h Thu Oct 17 11:12:54 2019 +0100 @@ -39,8 +39,8 @@ QString getFeatureDescription(LayerGeometryProvider *v, QPoint &) const override; bool snapToFeatureFrame(LayerGeometryProvider *v, sv_frame_t &frame, - int &resolution, - SnapType snap) const override; + int &resolution, + SnapType snap, int ycoord) const override; void drawStart(LayerGeometryProvider *v, QMouseEvent *) override; void drawDrag(LayerGeometryProvider *v, QMouseEvent *) override; diff -r ec837d223bd9 -r e6362cf5ff1d layer/TimeRulerLayer.cpp --- a/layer/TimeRulerLayer.cpp Thu Oct 17 10:26:21 2019 +0100 +++ b/layer/TimeRulerLayer.cpp Thu Oct 17 11:12:54 2019 +0100 @@ -51,7 +51,7 @@ bool TimeRulerLayer::snapToFeatureFrame(LayerGeometryProvider *v, sv_frame_t &frame, - int &resolution, SnapType snap) const + int &resolution, SnapType snap, int) const { auto model = ModelById::get(m_model); if (!model) { diff -r ec837d223bd9 -r e6362cf5ff1d layer/TimeRulerLayer.h --- a/layer/TimeRulerLayer.h Thu Oct 17 10:26:21 2019 +0100 +++ b/layer/TimeRulerLayer.h Thu Oct 17 11:12:54 2019 +0100 @@ -41,7 +41,8 @@ void setLabelHeight(LabelHeight h) { m_labelHeight = h; } LabelHeight getLabelHeight() const { return m_labelHeight; } - bool snapToFeatureFrame(LayerGeometryProvider *, sv_frame_t &, int &, SnapType) const override; + bool snapToFeatureFrame(LayerGeometryProvider *, sv_frame_t &, int &, + SnapType, int) const override; ColourSignificance getLayerColourSignificance() const override { return ColourIrrelevant; diff -r ec837d223bd9 -r e6362cf5ff1d layer/TimeValueLayer.cpp --- a/layer/TimeValueLayer.cpp Thu Oct 17 10:26:21 2019 +0100 +++ b/layer/TimeValueLayer.cpp Thu Oct 17 11:12:54 2019 +0100 @@ -687,11 +687,11 @@ TimeValueLayer::snapToFeatureFrame(LayerGeometryProvider *v, sv_frame_t &frame, int &resolution, - SnapType snap) const + SnapType snap, int ycoord) const { auto model = ModelById::getAs(m_model); if (!model) { - return Layer::snapToFeatureFrame(v, frame, resolution, snap); + return Layer::snapToFeatureFrame(v, frame, resolution, snap, ycoord); } // SnapLeft / SnapRight: return frame of nearest feature in that diff -r ec837d223bd9 -r e6362cf5ff1d layer/TimeValueLayer.h --- a/layer/TimeValueLayer.h Thu Oct 17 10:26:21 2019 +0100 +++ b/layer/TimeValueLayer.h Thu Oct 17 11:12:54 2019 +0100 @@ -46,11 +46,11 @@ QString getLabelPreceding(sv_frame_t) const override; bool snapToFeatureFrame(LayerGeometryProvider *v, sv_frame_t &frame, - int &resolution, - SnapType snap) const override; + int &resolution, + SnapType snap, int ycoord) const override; bool snapToSimilarFeature(LayerGeometryProvider *v, sv_frame_t &frame, - int &resolution, - SnapType snap) const override; + int &resolution, + SnapType snap) const override; void drawStart(LayerGeometryProvider *v, QMouseEvent *) override; void drawDrag(LayerGeometryProvider *v, QMouseEvent *) override; diff -r ec837d223bd9 -r e6362cf5ff1d view/Pane.cpp --- a/view/Pane.cpp Thu Oct 17 10:26:21 2019 +0100 +++ b/view/Pane.cpp Thu Oct 17 11:12:54 2019 +0100 @@ -1440,7 +1440,7 @@ if (layer && !m_shiftPressed && !qobject_cast(layer)) { // don't snap to secs layer->snapToFeatureFrame(this, snapFrame, - resolution, Layer::SnapLeft); + resolution, Layer::SnapLeft, e->y()); } if (snapFrame < 0) snapFrame = 0; @@ -2173,9 +2173,9 @@ if (layer && !m_shiftPressed && !qobject_cast(layer)) { // don't snap to secs layer->snapToFeatureFrame(this, snapFrameLeft, - resolution, Layer::SnapLeft); + resolution, Layer::SnapLeft, e->y()); layer->snapToFeatureFrame(this, snapFrameRight, - resolution, Layer::SnapRight); + resolution, Layer::SnapRight, e->y()); } // cerr << "snap: frame = " << mouseFrame << ", start frame = " << m_selectionStartFrame << ", left = " << snapFrameLeft << ", right = " << snapFrameRight << endl;