# HG changeset patch # User Chris Cannam # Date 1571304381 -3600 # Node ID ec837d223bd9985c10722208b344a9f56086c07d # Parent bdf284b297229a95a4e69d7a20a513f2bd0fb93b Update getPointToDrag to prefer boxes that are containing the mouse position in height as well as width diff -r bdf284b29722 -r ec837d223bd9 layer/BoxLayer.cpp --- a/layer/BoxLayer.cpp Wed Oct 16 16:20:12 2019 +0100 +++ b/layer/BoxLayer.cpp Thu Oct 17 10:26:21 2019 +0100 @@ -265,7 +265,7 @@ bool BoxLayer::getPointToDrag(LayerGeometryProvider *v, int x, int y, - Event &point) const + Event &point) const { auto model = ModelById::getAs(m_model); if (!model) return false; @@ -275,13 +275,47 @@ EventVector onPoints = model->getEventsCovering(frame); if (onPoints.empty()) return false; - int nearestDistance = -1; + Event bestContaining; for (const auto &p: onPoints) { - int distance = getYForValue(v, p.getValue()) - y; - if (distance < 0) distance = -distance; - if (nearestDistance == -1 || distance < nearestDistance) { - nearestDistance = distance; - point = p; + auto r = getRange(p); + if (y > getYForValue(v, r.first) || y < getYForValue(v, r.second)) { + SVCERR << "inPoints: rejecting " << p.toXmlString() << endl; + continue; + } + SVCERR << "inPoints: looking at " << p.toXmlString() << endl; + if (bestContaining == Event()) { + bestContaining = p; + continue; + } + auto br = getRange(bestContaining); + if (r.first < br.first && r.second > br.second) { + continue; + } + if (r.first > br.first && r.second < br.second) { + bestContaining = p; + continue; + } + if (p.getFrame() > bestContaining.getFrame() && + p.getFrame() + p.getDuration() < + bestContaining.getFrame() + bestContaining.getDuration()) { + bestContaining = p; + continue; + } + } + + if (bestContaining != Event()) { + point = bestContaining; + } else { + int nearestDistance = -1; + for (const auto &p: onPoints) { + int distance = std::min + (getYForValue(v, p.getValue()) - y, + getYForValue(v, p.getValue() + fabsf(p.getLevel())) - y); + if (distance < 0) distance = -distance; + if (nearestDistance == -1 || distance < nearestDistance) { + nearestDistance = distance; + point = p; + } } } @@ -307,7 +341,7 @@ QString BoxLayer::getFeatureDescription(LayerGeometryProvider *v, - QPoint &pos) const + QPoint &pos) const { int x = pos.x(); @@ -373,9 +407,9 @@ bool BoxLayer::snapToFeatureFrame(LayerGeometryProvider *v, - sv_frame_t &frame, - int &resolution, - SnapType snap) const + sv_frame_t &frame, + int &resolution, + SnapType snap) const { auto model = ModelById::getAs(m_model); if (!model) { diff -r bdf284b29722 -r ec837d223bd9 layer/BoxLayer.h --- a/layer/BoxLayer.h Wed Oct 16 16:20:12 2019 +0100 +++ b/layer/BoxLayer.h Thu Oct 17 10:26:21 2019 +0100 @@ -133,6 +133,10 @@ ChangeEventsCommand *m_editingCommand; VerticalScale m_verticalScale; + std::pair getRange(const Event &e) const { + return { e.getValue(), e.getValue() + fabsf(e.getLevel()) }; + } + void finish(ChangeEventsCommand *command) { Command *c = command->finish(); if (c) CommandHistory::getInstance()->addCommand(c, false);