changeset 922:26da827e8fb5 tonioni

Merge from cxx11 branch
author Chris Cannam
date Mon, 23 Mar 2015 11:26:28 +0000
parents 4968bbaf1ed8 (diff) 50be12cf2802 (current diff)
children 2a9f1eb6e0ed
files layer/FlexiNoteLayer.cpp layer/FlexiNoteLayer.h view/Overview.cpp view/Overview.h view/Pane.cpp
diffstat 5 files changed, 131 insertions(+), 49 deletions(-) [+]
line wrap: on
line diff
--- a/layer/FlexiNoteLayer.cpp	Wed Mar 11 13:30:37 2015 +0000
+++ b/layer/FlexiNoteLayer.cpp	Mon Mar 23 11:26:28 2015 +0000
@@ -1135,7 +1135,8 @@
 
     m_editingCommand->deletePoint(m_editingPoint);
 
-    std::cerr << "edit mode: " << m_editMode << std::endl;
+    std::cerr << "edit mode: " << m_editMode << " intelligent actions = "
+              << m_intelligentActions << std::endl;
     
     switch (m_editMode) {
     case LeftBoundary : {
@@ -1164,20 +1165,32 @@
             dragFrame = m_smallestRightNeighbourFrame - m_originalPoint.duration;
         }
         m_editingPoint.frame = dragFrame;
+
         m_editingPoint.value = float(value);
+
+        // Re-analyse region within +/- 1 semitone of the dragged value
+        float cents = 0;
+        int midiPitch = Pitch::getPitchForFrequency(m_editingPoint.value, &cents);
+        double lower = Pitch::getFrequencyForPitch(midiPitch - 1, cents);
+        double higher = Pitch::getFrequencyForPitch(midiPitch + 1, cents);
+        
+        emit reAnalyseRegion(m_editingPoint.frame,
+                             m_editingPoint.frame + m_editingPoint.duration,
+                             float(lower), float(higher));
         break;
     }
     case SplitNote: // nothing
         break;
     }
-    updateNoteValue(v, m_editingPoint);
+
+//    updateNoteValueFromPitchCurve(v, m_editingPoint);
     m_editingCommand->addPoint(m_editingPoint);
+
     std::cerr << "added new point(" << m_editingPoint.frame << "," << m_editingPoint.duration << ")" << std::endl;
-    
 }
 
 void
-FlexiNoteLayer::editEnd(View *, QMouseEvent *e)
+FlexiNoteLayer::editEnd(View *v, QMouseEvent *e)
 {
 //    SVDEBUG << "FlexiNoteLayer::editEnd(" << e->x() << "," << e->y() << ")" << endl;
     std::cerr << "FlexiNoteLayer::editEnd(" << e->x() << "," << e->y() << ")" << std::endl;
@@ -1188,6 +1201,15 @@
 
         QString newName = m_editingCommand->getName();
 
+        if (m_editMode == DragNote) {
+            //!!! command nesting is wrong?
+            emit materialiseReAnalysis();
+        }
+
+        m_editingCommand->deletePoint(m_editingPoint);
+        updateNoteValueFromPitchCurve(v, m_editingPoint);
+        m_editingCommand->addPoint(m_editingPoint);
+
         if (m_editingPoint.frame != m_originalPoint.frame) {
             if (m_editingPoint.value != m_originalPoint.value) {
                 newName = tr("Edit Point");
@@ -1210,7 +1232,7 @@
 FlexiNoteLayer::splitStart(View *v, QMouseEvent *e)
 {
     // GF: note splitting starts (!! remove printing soon)
-    std::cerr << "splitStart" << std::endl;
+    std::cerr << "splitStart (n.b. editStart will be called later, if the user drags the mouse)" << std::endl;
     if (!m_model) return;
 
     if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return;
@@ -1227,7 +1249,6 @@
     m_editing = true;
     m_dragStartX = e->x();
     m_dragStartY = e->y();
-    
 }
 
 void
@@ -1280,10 +1301,10 @@
                            note.level, note.label);
                        
         if (m_intelligentActions) {
-            if (updateNoteValue(v, newNote1)) {
+            if (updateNoteValueFromPitchCurve(v, newNote1)) {
                 command->addPoint(newNote1);
             }
-            if (updateNoteValue(v, newNote2)) {
+            if (updateNoteValueFromPitchCurve(v, newNote2)) {
                 command->addPoint(newNote2);
             }
         } else {
@@ -1339,22 +1360,23 @@
 {
     // Better than we used to do, but still not very satisfactory
 
-    cerr << "FlexiNoteLayer::getAssociatedPitchModel()" << endl;
+//    cerr << "FlexiNoteLayer::getAssociatedPitchModel()" << endl;
 
     for (int i = 0; i < v->getLayerCount(); ++i) {
         Layer *layer = v->getLayer(i);
         if (layer &&
             layer->getLayerPresentationName() != "candidate") {
-            cerr << "FlexiNoteLayer::getAssociatedPitchModel: looks like our layer is " << layer << endl;
+//            cerr << "FlexiNoteLayer::getAssociatedPitchModel: looks like our layer is " << layer << endl;
             SparseTimeValueModel *model = qobject_cast<SparseTimeValueModel *>
                 (layer->getModel());
-            cerr << "FlexiNoteLayer::getAssociatedPitchModel: and its model is " << model << endl;
+//            cerr << "FlexiNoteLayer::getAssociatedPitchModel: and its model is " << model << endl;
             if (model && model->getScaleUnits() == "Hz") {
                 cerr << "FlexiNoteLayer::getAssociatedPitchModel: it's good, returning " << model << endl;
                 return model;
             }
         }
     }
+    cerr << "FlexiNoteLayer::getAssociatedPitchModel: failed to find a model" << endl;
     return 0;
 }
 
@@ -1388,7 +1410,7 @@
 
         command->deletePoint(note);
 
-        if (updateNoteValue(v, newNote)) {
+        if (updateNoteValueFromPitchCurve(v, newNote)) {
             command->addPoint(newNote);
         }
     }
@@ -1434,13 +1456,14 @@
         ++i;
     }
 
-    updateNoteValue(v, newNote);
+    updateNoteValueFromPitchCurve(v, newNote);
     command->addPoint(newNote);
     finish(command);
 }
 
 bool
-FlexiNoteLayer::updateNoteValue(View *v, FlexiNoteModel::Point &note) const
+FlexiNoteLayer::updateNoteValueFromPitchCurve(View *v,
+                                              FlexiNoteModel::Point &note) const
 {
     SparseTimeValueModel *model = getAssociatedPitchModel(v);
     if (!model) return false;
@@ -1475,6 +1498,8 @@
     } else {
         median = pitchValues[size/2];
     }
+
+    std::cerr << "updateNoteValueFromPitchCurve: corrected from " << note.value << " to median " << median << std::endl;
     
     note.value = float(median);
 
@@ -1492,21 +1517,31 @@
         return; 
     }
 
-    bool closeToLeft = false, closeToRight = false, closeToTop = false, closeToBottom = false;
-    getRelativeMousePosition(v, note, e->x(), e->y(), closeToLeft, closeToRight, closeToTop, closeToBottom);
-    // if (!closeToLeft) return;
-    // if (closeToTop) v->setCursor(Qt::SizeVerCursor);
+    bool closeToLeft = false, closeToRight = false,
+        closeToTop = false, closeToBottom = false;
+    getRelativeMousePosition(v, note, e->x(), e->y(),
+                             closeToLeft, closeToRight,
+                             closeToTop, closeToBottom);
     
-    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);
-
-    std::cerr << "Mouse moved in edit mode over FlexiNoteLayer" << std::endl;
-    // v->setCursor(Qt::SizeHorCursor);
-
+    if (closeToLeft) {
+        v->setCursor(Qt::SizeHorCursor);
+        m_editMode = LeftBoundary;
+        cerr << "edit mode -> LeftBoundary" << endl;
+    } else if (closeToRight) {
+        v->setCursor(Qt::SizeHorCursor);
+        m_editMode = RightBoundary;
+        cerr << "edit mode -> RightBoundary" << endl;
+    } else if (closeToTop) {
+        v->setCursor(Qt::CrossCursor);
+        m_editMode = DragNote;
+        cerr << "edit mode -> DragNote" << endl;
+    } else if (closeToBottom) {
+        v->setCursor(Qt::UpArrowCursor);
+        m_editMode = SplitNote;
+        cerr << "edit mode -> SplitNote" << endl;
+    } else {
+        v->setCursor(Qt::ArrowCursor);
+    }
 }
 
 void
--- a/layer/FlexiNoteLayer.h	Wed Mar 11 13:30:37 2015 +0000
+++ b/layer/FlexiNoteLayer.h	Mon Mar 23 11:26:28 2015 +0000
@@ -163,6 +163,10 @@
     virtual double getValueForY(View *v, int y) const;
     virtual QString getScaleUnits() const;
 
+signals:
+    void reAnalyseRegion(sv_frame_t, sv_frame_t, float, float);
+    void materialiseReAnalysis();
+    
 protected:
     void getScaleExtents(View *, double &min, double &max, bool &log) const;
     bool shouldConvertMIDIToHz() const;
@@ -173,9 +177,13 @@
 
     bool getPointToDrag(View *v, int x, int y, FlexiNoteModel::Point &) const;
     bool getNoteToEdit(View *v, int x, int y, FlexiNoteModel::Point &) const;
-    void getRelativeMousePosition(View *v, FlexiNoteModel::Point &note, int x, int y, bool &closeToLeft, bool &closeToRight, bool &closeToTop, bool &closeToBottom) const;
+    void getRelativeMousePosition(View *v, FlexiNoteModel::Point &note,
+                                  int x, int y,
+                                  bool &closeToLeft, bool &closeToRight,
+                                  bool &closeToTop, bool &closeToBottom) const;
     SparseTimeValueModel *getAssociatedPitchModel(View *v) const;
-    bool updateNoteValue(View *v, FlexiNoteModel::Point &note) const;
+    bool updateNoteValueFromPitchCurve(View *v,
+                                       FlexiNoteModel::Point &note) const;
     void splitNotesAt(View *v, sv_frame_t frame, QMouseEvent *e);
 
     FlexiNoteModel *m_model;
--- a/view/Overview.cpp	Wed Mar 11 13:30:37 2015 +0000
+++ b/view/Overview.cpp	Mon Mar 23 11:26:28 2015 +0000
@@ -144,6 +144,20 @@
     if (changed) update();
 }
 
+QColor
+Overview::getFillWithin() const
+{
+    return Qt::transparent;
+}
+
+QColor
+Overview::getFillWithout() const
+{
+    QColor c = palette().window().color();
+    c.setAlpha(100);
+    return c;
+}
+
 void
 Overview::paintEvent(QPaintEvent *e)
 {
@@ -184,21 +198,23 @@
 
     QPainter paint;
     paint.begin(this);
-
+    paint.setClipRegion(e->region());
+    paint.setRenderHints(QPainter::Antialiasing);
+    
     QRect r(rect());
 
-    if (e) {
-	r = e->rect();
-	paint.setClipRect(r);
-    }
+    // We paint a rounded rect for each distinct set of view extents,
+    // and we colour in the inside and outside of the rect that
+    // corresponds to the current view. (One small caveat -- we don't
+    // know which rect that is yet. We'll have to figure it out
+    // somehow...)
 
-    paint.setPen(getForeground());
+    std::set<std::pair<int, int> > extents;
+    std::vector<QRect> rects;
+    QRect primary;
 
     int y = 0;
 
-    sv_frame_t prevx0 = -10;
-    sv_frame_t prevx1 = -10;
-
     for (ViewSet::iterator i = m_views.begin(); i != m_views.end(); ++i) {
 	if (!*i) continue;
 
@@ -219,15 +235,35 @@
 	int x0 = getXForFrame(f0);
 	int x1 = getXForFrame(f1);
 
-	if (x0 != prevx0 || x1 != prevx1) {
+	if (x1 <= x0) x1 = x0 + 1;
+
+        std::pair<int, int> extent(x0, x1);
+
+        if (extents.find(extent) == extents.end()) {
+
 	    y += height() / 10 + 1;
-	    prevx0 = x0;
-	    prevx1 = x1;
-	}
+            extents.insert(extent);
 
-	if (x1 <= x0) x1 = x0 + 1;
-	
-	paint.drawRect(x0, y, x1 - x0, height() - 2 * y);
+            QRect vr(x0, y, x1 - x0, height() - 2 * y);
+            rects.push_back(vr);
+            primary = vr; //!!! for now
+        }
+    }
+
+    QPainterPath without;
+    without.addRoundedRect(primary, 8, 8);
+    without.addRect(rect());
+    paint.setPen(Qt::NoPen);
+    paint.setBrush(getFillWithout());
+    paint.drawPath(without);
+
+    paint.setBrush(getFillWithin());
+    paint.drawRoundedRect(primary, 8, 8);
+    
+    foreach (QRect vr, rects) {
+        paint.setBrush(Qt::NoBrush);
+        paint.setPen(QPen(getForeground(), 2));
+        paint.drawRoundedRect(vr, 8, 8);
     }
 
     paint.end();
--- a/view/Overview.h	Wed Mar 11 13:30:37 2015 +0000
+++ b/view/Overview.h	Mon Mar 23 11:26:28 2015 +0000
@@ -59,6 +59,9 @@
     virtual void leaveEvent(QEvent *);
     virtual bool shouldLabelSelections() const { return false; }
 
+    QColor getFillWithin() const;
+    QColor getFillWithout() const;
+    
     QPoint m_clickPos;
     QPoint m_mousePos;
     bool m_clickedInRange;
--- a/view/Pane.cpp	Wed Mar 11 13:30:37 2015 +0000
+++ b/view/Pane.cpp	Mon Mar 23 11:26:28 2015 +0000
@@ -1740,9 +1740,9 @@
 
             if (!editSelectionDrag(e)) {
 
-                Layer *layer = getInteractionLayer();
-
-                if (layer && layer->isLayerEditable()) {
+                Layer *layer = getTopFlexiNoteLayer();
+
+                if (layer) {
 
                     int x = e->x();
                     int y = e->y();