diff layer/NoteLayer.cpp @ 550:d666f5f8b154

* Make a better job of picking the proper point to drag, edit, delete etc in note and region layers * Some work to do with region dragging, but this still needs more thought
author Chris Cannam
date Mon, 28 Sep 2009 12:29:12 +0000
parents 1dd2cddc32eb
children c2ba2796cbee
line wrap: on
line diff
--- a/layer/NoteLayer.cpp	Fri Sep 25 12:02:22 2009 +0000
+++ b/layer/NoteLayer.cpp	Mon Sep 28 12:29:12 2009 +0000
@@ -404,6 +404,34 @@
     return usePoints;
 }
 
+bool
+NoteLayer::getPointToDrag(View *v, int x, int y, NoteModel::Point &p) const
+{
+    if (!m_model) return false;
+
+    long frame = v->getFrameForX(x);
+
+    NoteModel::PointList onPoints = m_model->getPoints(frame);
+    if (onPoints.empty()) return false;
+
+    std::cerr << "frame " << frame << ": " << onPoints.size() << " candidate points" << std::endl;
+
+    int nearestDistance = -1;
+
+    for (NoteModel::PointList::const_iterator i = onPoints.begin();
+         i != onPoints.end(); ++i) {
+        
+        int distance = getYForValue(v, (*i).value) - y;
+        if (distance < 0) distance = -distance;
+        if (nearestDistance == -1 || distance < nearestDistance) {
+            nearestDistance = distance;
+            p = *i;
+        }
+    }
+
+    return true;
+}
+
 QString
 NoteLayer::getFeatureDescription(View *v, QPoint &pos) const
 {
@@ -818,10 +846,12 @@
 {
     if (!m_model) return;
 
-    NoteModel::PointList points = getLocalPoints(v, e->x());
-    if (points.empty()) return;
+//    NoteModel::PointList points = getLocalPoints(v, e->x());
+//    if (points.empty()) return;
 
-    m_editingPoint = *points.begin();
+//    m_editingPoint = *points.begin();
+
+    if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return;
 
     if (m_editingCommand) {
 	finish(m_editingCommand);
@@ -843,13 +873,18 @@
 
     m_editing = false;
 
+/*
     NoteModel::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 NoteModel::EditCommand
-        (m_model, tr("Erase Point"));
+    NoteModel::Point p(0);
+    if (!getPointToDrag(v, e->x(), e->y(), p)) return;
+    if (p.frame != m_editingPoint.frame || p.value != m_editingPoint.value) return;
+
+    m_editingCommand = new NoteModel::EditCommand(m_model, tr("Erase Point"));
 
     m_editingCommand->deletePoint(m_editingPoint);
 
@@ -865,10 +900,14 @@
 
     if (!m_model) return;
 
+/*
     NoteModel::PointList points = getLocalPoints(v, e->x());
     if (points.empty()) return;
 
     m_editingPoint = *points.begin();
+*/
+
+    if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return;
     m_originalPoint = m_editingPoint;
 
     if (m_editingCommand) {
@@ -935,11 +974,15 @@
 NoteLayer::editOpen(View *v, QMouseEvent *e)
 {
     if (!m_model) return false;
-
+/*
     NoteModel::PointList points = getLocalPoints(v, e->x());
     if (points.empty()) return false;
+*/
 
-    NoteModel::Point note = *points.begin();
+    NoteModel::Point note(0);
+    if (!getPointToDrag(v, e->x(), e->y(), note)) return false;
+
+//    NoteModel::Point note = *points.begin();
 
     ItemEditDialog *dialog = new ItemEditDialog
         (m_model->getSampleRate(),