changeset 1546:ec837d223bd9

Update getPointToDrag to prefer boxes that are containing the mouse position in height as well as width
author Chris Cannam
date Thu, 17 Oct 2019 10:26:21 +0100
parents bdf284b29722
children e6362cf5ff1d
files layer/BoxLayer.cpp layer/BoxLayer.h
diffstat 2 files changed, 49 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- 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<BoxModel>(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<BoxModel>(m_model);
     if (!model) {
--- 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<float, float> 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);