diff layer/FlexiNoteLayer.cpp @ 651:76c5dfe333ee tonioni

introduced horizongal note editing constraints; debugged note edit
author matthiasm
date Mon, 17 Jun 2013 18:00:24 +0100
parents 2ad082c5a090
children 35c3323a78a2
line wrap: on
line diff
--- a/layer/FlexiNoteLayer.cpp	Sun Jun 16 20:40:05 2013 +0100
+++ b/layer/FlexiNoteLayer.cpp	Mon Jun 17 18:00:24 2013 +0100
@@ -802,28 +802,28 @@
     paint.setPen(getBaseQColor());
     paint.setBrush(brushColour);
 
-    if (shouldIlluminate &&
-            // "illuminatePoint == p"
-            !FlexiNoteModel::Point::Comparator()(illuminatePoint, p) &&
-            !FlexiNoteModel::Point::Comparator()(p, illuminatePoint)) {
-
-            paint.setPen(v->getForeground());
-            paint.setBrush(v->getForeground());
-
-            QString vlabel = QString("%1%2").arg(p.value).arg(m_model->getScaleUnits());
-            v->drawVisibleText(paint, 
-                               x - paint.fontMetrics().width(vlabel) - 2,
-                               y + paint.fontMetrics().height()/2
-                                 - paint.fontMetrics().descent(), 
-                               vlabel, View::OutlinedText);
-
-            QString hlabel = RealTime::frame2RealTime
-                (p.frame, m_model->getSampleRate()).toText(true).c_str();
-            v->drawVisibleText(paint, 
-                               x,
-                               y - h/2 - paint.fontMetrics().descent() - 2,
-                               hlabel, View::OutlinedText);
-    }
+    // if (shouldIlluminate &&
+    //         // "illuminatePoint == p"
+    //         !FlexiNoteModel::Point::Comparator()(illuminatePoint, p) &&
+    //         !FlexiNoteModel::Point::Comparator()(p, illuminatePoint)) {
+    // 
+    //         paint.setPen(v->getForeground());
+    //         paint.setBrush(v->getForeground());
+    // 
+    //         QString vlabel = QString("%1%2").arg(p.value).arg(m_model->getScaleUnits());
+    //         v->drawVisibleText(paint, 
+    //                            x - paint.fontMetrics().width(vlabel) - 2,
+    //                            y + paint.fontMetrics().height()/2
+    //                              - paint.fontMetrics().descent(), 
+    //                            vlabel, View::OutlinedText);
+    // 
+    //         QString hlabel = RealTime::frame2RealTime
+    //             (p.frame, m_model->getSampleRate()).toText(true).c_str();
+    //         v->drawVisibleText(paint, 
+    //                            x,
+    //                            y - h/2 - paint.fontMetrics().descent() - 2,
+    //                            hlabel, View::OutlinedText);
+    // }
     
     paint.drawRect(x, y - h/2, w, h);
     }
@@ -943,10 +943,10 @@
     if (!m_model) return;
 
     if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return;
-    m_originalPoint = m_editingPoint;
+    m_originalPoint = FlexiNote(m_editingPoint);
     
-    if (m_editMode == rightBoundary) {
-        m_dragPointX = v->getXForFrame(m_editingPoint.frame + m_editingPoint.duration);
+    if (m_editMode == RightBoundary) {
+        m_dragPointX =   v->getXForFrame(m_editingPoint.frame + m_editingPoint.duration);
     } else {
         m_dragPointX = v->getXForFrame(m_editingPoint.frame);
     }
@@ -960,6 +960,29 @@
     m_editing = true;
     m_dragStartX = e->x();
     m_dragStartY = e->y();
+    
+    long onset = m_originalPoint.frame;
+    long offset = m_originalPoint.frame + m_originalPoint.duration - 1;
+    
+    m_greatestLeftNeighbourFrame = -1;
+    m_smallestRightNeighbourFrame = std::numeric_limits<long>::max();
+    
+    for (FlexiNoteModel::PointList::const_iterator i = m_model->getPoints().begin();
+         i != m_model->getPoints().end(); ++i) {
+        FlexiNote currentNote = *i;
+        
+        // left boundary
+        if (currentNote.frame + currentNote.duration - 1 < onset) {
+            m_greatestLeftNeighbourFrame = currentNote.frame + currentNote.duration - 1;
+        }
+        
+        // right boundary
+        if (currentNote.frame > offset) {
+            m_smallestRightNeighbourFrame = currentNote.frame;
+            break;
+        }
+    }
+    std::cerr << "note frame: " << onset << ", left boundary: " << m_greatestLeftNeighbourFrame << ", right boundary: " << m_smallestRightNeighbourFrame << std::endl;
 }
 
 void
@@ -978,7 +1001,7 @@
     long frame = v->getFrameForX(newx);
     if (frame < 0) frame = 0;
     frame = frame / m_model->getResolution() * m_model->getResolution();
-
+    
     float value = getValueForY(v, newy);
 
     if (!m_editingCommand) {
@@ -987,14 +1010,35 @@
     }
 
     m_editingCommand->deletePoint(m_editingPoint);
-    if (m_editMode == leftBoundary) 
-        m_editingPoint.duration = m_editingPoint.duration + (m_editingPoint.frame - frame); // GF: left boundary change
-    if (m_editMode == rightBoundary) {
-        m_editingPoint.duration = frame - m_editingPoint.frame; // GF: right boundary change
-    } else {
-        m_editingPoint.frame = frame;
+
+    std::cerr << "edit mode: " << m_editMode << std::endl;
+    switch (m_editMode) {
+        case LeftBoundary : {
+            if ((frame > m_greatestLeftNeighbourFrame) 
+                 && (frame < m_originalPoint.frame + m_originalPoint.duration - 1)
+                 && (frame < m_smallestRightNeighbourFrame)) {
+                m_editingPoint.duration = m_editingPoint.frame + m_editingPoint.duration - frame + 1;
+                m_editingPoint.frame = frame;
+            }
+            break;
+        }
+        case RightBoundary : {
+            long tempDuration = frame - m_originalPoint.frame;
+            if (tempDuration > 0 && m_originalPoint.frame + tempDuration - 1 < m_smallestRightNeighbourFrame) {
+                m_editingPoint.duration = tempDuration;
+            }
+            break;
+        }
+        case DragNote : {
+            if (frame <= m_smallestRightNeighbourFrame - m_editingPoint.duration
+                && frame > m_greatestLeftNeighbourFrame) {
+                m_editingPoint.frame = frame; // only move if it doesn't overlap with right note or left note
+            }
+            m_editingPoint.value = value;
+            break;
+        }
     }
-    m_editingPoint.value = value;
+    
     m_editingCommand->addPoint(m_editingPoint);
     std::cerr << "added new point(" << m_editingPoint.frame << "," << m_editingPoint.duration << ")" << std::endl;
     
@@ -1025,6 +1069,8 @@
     m_editingCommand->setName(newName);
     finish(m_editingCommand);
     }
+    
+    setVerticalRangeToNoteRange();
 
     m_editingCommand = 0;
     m_editing = false;
@@ -1059,7 +1105,7 @@
 {
     // GF: note splitting ends. (!! remove printing soon)
     std::cerr << "splitEnd" << std::endl;
-    if (!m_model || !m_editing || m_editMode != splitNote) return;
+    if (!m_model || !m_editing || m_editMode != SplitNote) return;
 
     int xdist = e->x() - m_dragStartX;
     int ydist = e->y() - m_dragStartY;
@@ -1114,10 +1160,10 @@
     // if (!closeToLeft) return;
     // if (closeToTop) v->setCursor(Qt::SizeVerCursor);
     
-    if (closeToLeft) { v->setCursor(Qt::SizeHorCursor); m_editMode = leftBoundary; return; }
-    if (closeToRight) { v->setCursor(Qt::SizeHorCursor); m_editMode = rightBoundary; return; }
-    if (closeToTop) { v->setCursor(Qt::CrossCursor);  m_editMode = dragNote; return; }
-    if (closeToBottom) { v->setCursor(Qt::UpArrowCursor); m_editMode = splitNote; return; }
+    if (closeToLeft) { v->setCursor(Qt::SizeHorCursor); m_editMode = LeftBoundary; return; }
+    if (closeToRight) { v->setCursor(Qt::SizeHorCursor); m_editMode = RightBoundary; return; }
+    if (closeToTop) { v->setCursor(Qt::CrossCursor);  m_editMode = DragNote; return; }
+    if (closeToBottom) { v->setCursor(Qt::UpArrowCursor); m_editMode = SplitNote; return; }
 
     v->setCursor(Qt::ArrowCursor);
 
@@ -1132,7 +1178,7 @@
     // GF: TODO: consoloidate the tolerance values
     if (!m_model) return;
 
-    int ctol = 2;
+    int ctol = 0;
     int noteStartX = v->getXForFrame(note.frame);
     int noteEndX = v->getXForFrame(note.frame + note.duration);
     int noteValueY = getYForValue(v,note.value);
@@ -1144,7 +1190,7 @@
     if (y >= noteStartY-ctol && y <= noteEndY+ctol && x >= noteStartX-ctol && x <= noteEndX+ctol) closeToNote = true;
     if (!closeToNote) return;
     
-    int tol = 4;
+    int tol = NOTE_HEIGHT / 2;
     
     if (x >= noteStartX - tol && x <= noteStartX + tol) closeToLeft = true;
     if (x >= noteEndX - tol && x <= noteEndX + tol) closeToRight = true;
@@ -1448,4 +1494,22 @@
     if (ok && alsoOk) setDisplayExtents(min, max);
 }
 
+void
+FlexiNoteLayer::setVerticalRangeToNoteRange()
+{
+    float minf = std::numeric_limits<float>::max();;
+    float maxf = 0;
+    for (FlexiNoteModel::PointList::const_iterator i = m_model->getPoints().begin();
+         i != m_model->getPoints().end(); ++i) {
+             FlexiNote note = *i;
+             if (note.value < minf) minf = note.value;
+             else if (note.value > maxf) maxf = note.value;
+             std::cerr << "min frequency:" << minf << ", max frequency: " << maxf << std::endl;
+    }
+    
+	if (this) {
+            setDisplayExtents(minf,maxf);
+    }
+}
 
+