changeset 650:12d570c27d85 tonioni

split drag delete
author matthiasm
date Sun, 16 Jun 2013 00:16:37 +0100
parents f61a54364d1d
children be7c9dc84f26
files layer/FlexiNoteLayer.cpp layer/FlexiNoteLayer.h layer/Layer.h view/Pane.cpp
diffstat 4 files changed, 194 insertions(+), 52 deletions(-) [+]
line wrap: on
line diff
--- a/layer/FlexiNoteLayer.cpp	Sat Jun 15 19:52:06 2013 +0100
+++ b/layer/FlexiNoteLayer.cpp	Sun Jun 16 00:16:37 2013 +0100
@@ -472,6 +472,34 @@
     return true;
 }
 
+bool
+FlexiNoteLayer::getLeftNeighbour(View *v, FlexiNote note, FlexiNote &leftNeighbour) const {
+    // MM: this is necessary (I think) to restrict the movement of notes to the left
+    if (!m_model) return false;
+    
+    FlexiNoteModel::PointList onPoints = m_model->getPoints(0, note.frame - 1);
+    if (!onPoints.empty())
+    {
+        leftNeighbour = *onPoints.end();
+        return true;
+    }
+    return false;
+}
+
+bool
+FlexiNoteLayer::getRightNeighbour(View *v, FlexiNote note, FlexiNote &rightNeighbour) const {
+    // MM: this is necessary (I think) to restrict the movement of notes to the right
+    if (!m_model) return false;
+    
+    FlexiNoteModel::PointList onPoints = m_model->getPoints(note.frame + note.duration);
+    if (!onPoints.empty())
+    {
+        rightNeighbour = *onPoints.begin();
+        return true;
+    }
+    return false;
+}
+
 QString
 FlexiNoteLayer::getFeatureDescription(View *v, QPoint &pos) const
 {
@@ -1019,68 +1047,161 @@
 }
 
 void
-FlexiNoteLayer::splitStart(View *v, QMouseEvent *e)
+FlexiNoteLayer::multiStart(View *v, QMouseEvent *e)
 {
-    // GF: note splitting starts (!! remove printing soon)
-    std::cerr << "splitStart" << std::endl;
+    std::cerr << "multiStart" << std::endl;
     if (!m_model) return;
 
+    if (m_editingCommand) {
+        finish(m_editingCommand);
+        m_editingCommand = 0;
+    }
+    
     if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return;
-    // m_originalPoint = m_editingPoint;
-    // 
-    // m_dragPointX = v->getXForFrame(m_editingPoint.frame);
-    // m_dragPointY = getYForValue(v, m_editingPoint.value);
+    bool closeToLeft = false, closeToRight = false, closeToTop = false, closeToBottom = false;
+    getRelativeMousePosition(v, m_editingPoint, e->x(), e->y(), closeToLeft, closeToRight, closeToTop, closeToBottom);
 
-    if (m_editingCommand) {
-    finish(m_editingCommand);
-    m_editingCommand = 0;
+    std::cerr << closeToLeft << " " << closeToRight << " " << closeToTop << " " << closeToBottom << std::endl;
+    
+    if (closeToLeft) 
+    {
+        std::cerr << "... move left boundary" << std::endl;
+
+        if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return;
+        m_originalPoint = m_editingPoint;
+        
+        m_editing = true;
+        m_multiEditMode = MoveLeftBoundary;
+        m_dragStartX = e->x();
+        m_dragStartY = e->y();
+        
+    } else if (closeToTop) 
+    {
+        // MM: note delete starts
+        std::cerr << "... delete" << std::endl;
+        if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return;
+        FlexiNoteModel::EditCommand *command = new FlexiNoteModel::EditCommand
+            (m_model, tr("Edit Point"));
+        command->deletePoint(m_editingPoint);
+        finish(command);
+        m_editing = false;
+        m_editingPoint = 0;
+
+    } else if (closeToBottom) 
+    {
+        // GF: note splitting starts (!! remove printing soon)
+        std::cerr << "... split" << std::endl;
+        m_editing = true;
+        m_multiEditMode = Split;
+        m_dragStartX = e->x();
+        m_dragStartY = e->y();
     }
+    return;
+}
 
-    m_editing = true;
-    m_dragStartX = e->x();
-    m_dragStartY = e->y();
+
+void
+FlexiNoteLayer::multiDrag(View *v, QMouseEvent *e)
+{
+    // GF: note splitting ends. (!! remove printing soon)
+    std::cerr << "multiDrag" << std::endl;
+    if (!m_model || !m_editing) return;
     
+    switch (m_multiEditMode)
+    {
+        case MoveLeftBoundary :
+        {
+            long frame = v->getFrameForX(e->x());
+            long duration = m_originalPoint.duration - (frame - m_originalPoint.frame);
+            
+            if (!m_editingCommand) {
+            m_editingCommand = new FlexiNoteModel::EditCommand(m_model,
+                                      tr("Drag Point"));
+            }
+
+            m_editingCommand->deletePoint(m_editingPoint);
+            m_editingPoint.frame = frame;
+            m_editingPoint.duration = duration;
+            m_editingCommand->addPoint(m_editingPoint);
+            
+        }
+        default : return;
+    }
+    return;
 }
 
 void
-FlexiNoteLayer::splitEnd(View *v, QMouseEvent *e)
+FlexiNoteLayer::multiEnd(View *v, QMouseEvent *e)
 {
     // GF: note splitting ends. (!! remove printing soon)
-    std::cerr << "splitEnd" << std::endl;
+    std::cerr << "multiEnd" << std::endl;
     if (!m_model || !m_editing) return;
+    m_editing = false;
+    
+    switch (m_multiEditMode)
+    {
+        case MoveLeftBoundary :
+        {
+            std::cerr << "... move left boundary" << std::endl;
 
-    int xdist = e->x() - m_dragStartX;
-    int ydist = e->y() - m_dragStartY;
-    if (xdist != 0 || ydist != 0) { 
-        std::cerr << "mouse moved" << std::endl;    
-        return; 
+
+            if (m_editingCommand) {
+
+                QString newName = m_editingCommand->getName();
+
+                if (m_editingPoint.frame != m_originalPoint.frame) {
+                    newName = tr("Relocate Point");
+                }
+             
+                m_editingCommand->setName(newName);
+                finish(m_editingCommand);
+            }
+
+            m_editingCommand = 0;
+            m_editing = false;
+
+        }
+        case Split : 
+        {
+
+            // MM simpler declaration
+            FlexiNote note(0);
+            if (!getNoteToEdit(v, m_dragStartX, m_dragStartY, note)) return;
+
+            long frame = v->getFrameForX(e->x());
+
+            int gap = 100; // MM: I prefer a gap of 0, but we can decide later
+
+            // MM: changed this a bit, to make it slightly clearer
+            FlexiNote newNote1(note.frame, note.value, 
+                               frame - note.frame - gap, 
+                               note.level, note.label);
+
+            FlexiNote newNote2(frame, note.value, 
+                               note.duration - newNote1.duration, 
+                               note.level, note.label);
+            FlexiNoteModel::EditCommand *command = new FlexiNoteModel::EditCommand
+                (m_model, tr("Edit Point"));
+
+            command->deletePoint(note);
+            command->addPoint(newNote1);
+            command->addPoint(newNote2);
+            finish(command);
+        }
     }
 
-    // MM simpler declaration
-    FlexiNote note(0);
-    if (!getPointToDrag(v, e->x(), e->y(), note)) return;
+    return;
+}
 
-    long frame = v->getFrameForX(e->x());
-
-    int gap = 0; // MM: I prefer a gap of 0, but we can decide later
-    
-    // MM: changed this a bit, to make it slightly clearer
-    FlexiNote newNote1(note.frame, note.value, 
-                       frame - note.frame - gap, 
-                       note.level, note.label);
-    
-    FlexiNote newNote2(frame, note.value, 
-                       note.duration - newNote1.duration, 
-                       note.level, note.label);
-
-    FlexiNoteModel::EditCommand *command = new FlexiNoteModel::EditCommand
-        (m_model, tr("Edit Point"));
-    command->deletePoint(note);
-    command->addPoint(newNote1);
-    command->addPoint(newNote2);
-    finish(command);
-    
-}
+// void
+// FlexiNoteLayer::moveBoundaryStart(View *v, QMouseEvent *e)
+// {
+// }
+// 
+// void
+// FlexiNoteLayer::moveBoundaryEnd(View *v, QMouseEvent *e)
+// {
+// }
 
 void 
 FlexiNoteLayer::mouseMoveEvent(View *v, QMouseEvent *e)
--- a/layer/FlexiNoteLayer.h	Sat Jun 15 19:52:06 2013 +0100
+++ b/layer/FlexiNoteLayer.h	Sun Jun 16 00:16:37 2013 +0100
@@ -27,6 +27,14 @@
 class View;
 class QPainter;
 
+enum MultiEditMode
+{
+    MoveLeftBoundary,
+    MoveRightBoundary,
+    Delete,
+    Split
+};
+
 class FlexiNoteLayer : public SingleColourLayer
 {
     Q_OBJECT
@@ -54,8 +62,9 @@
     virtual void editDrag(View *v, QMouseEvent *);
     virtual void editEnd(View *v, QMouseEvent *);
 
-    virtual void splitStart(View *v, QMouseEvent *);
-    virtual void splitEnd(View *v, QMouseEvent *);
+    virtual void multiStart(View *v, QMouseEvent *);
+    virtual void multiDrag(View *v, QMouseEvent *);
+    virtual void multiEnd(View *v, QMouseEvent *);
 
     virtual void mouseMoveEvent(View *v, QMouseEvent *);
 
@@ -146,10 +155,13 @@
 
     bool getPointToDrag(View *v, int x, int y, FlexiNoteModel::Point &) const;
     bool getNoteToEdit(View *v, int x, int y, FlexiNoteModel::Point &) const;
+    bool getLeftNeighbour(View *v, FlexiNote note, FlexiNote &leftNeighbour) const;
+    bool getRightNeighbour(View *v, FlexiNote note, FlexiNote &rightNeighbour) const;
     void getRelativeMousePosition(View *v, FlexiNoteModel::Point &note, int x, int y, bool &closeToLeft, bool &closeToRight, bool &closeToTop, bool &closeToBottom) const;
 
     FlexiNoteModel *m_model;
     bool m_editing;
+    MultiEditMode m_multiEditMode;
     int m_dragPointX;
     int m_dragPointY;
     int m_dragStartX;
--- a/layer/Layer.h	Sat Jun 15 19:52:06 2013 +0100
+++ b/layer/Layer.h	Sun Jun 16 00:16:37 2013 +0100
@@ -229,9 +229,10 @@
     virtual void editDrag(View *, QMouseEvent *) { }
     virtual void editEnd(View *, QMouseEvent *) { }
 
-    virtual void splitStart(View *, QMouseEvent *) { }
-    virtual void splitEnd(View *, QMouseEvent *) { }
-
+    virtual void multiStart(View *, QMouseEvent *) { }
+    virtual void multiDrag(View *, QMouseEvent *) { }
+    virtual void multiEnd(View *, QMouseEvent *) { }
+    
     // Measurement rectangle (or equivalent).  Unlike draw and edit,
     // the base Layer class can provide working implementations of
     // these for most situations.
--- a/view/Pane.cpp	Sat Jun 15 19:52:06 2013 +0100
+++ b/view/Pane.cpp	Sun Jun 16 00:16:37 2013 +0100
@@ -1387,7 +1387,7 @@
         std::cerr << "mouse pressed in note edit mode" << std::endl;
         Layer *layer = getSelectedLayer();
         if (layer && layer->isLayerEditable()) {
-            layer->splitStart(this, e); 
+            layer->multiStart(this, e); 
         }
 
     } else if (mode == ViewManager::EditMode) {
@@ -1491,7 +1491,7 @@
         //GF: handle mouse release for NoteEditMode (note: works but will need to re-think this a bit later)
         Layer *layer = getSelectedLayer();
         if (layer && layer->isLayerEditable()) {
-            layer->splitEnd(this, e);
+            layer->multiEnd(this, e);
             update(); }
 
         if (m_editing) {
@@ -1722,6 +1722,14 @@
         }
 
         update();
+    } else if (mode == ViewManager::NoteEditMode) {
+
+        Layer *layer = getTopLayer();
+        if (layer) {
+            layer->multiDrag(this, e);
+        }
+
+        update();
     }
 }
 
@@ -2463,7 +2471,7 @@
 
     // GF: NoteEditMode uses the same default cursor as EditMode, but it will change in a context sensitive manner.
     case ViewManager::NoteEditMode:
-    setCursor(Qt::UpArrowCursor);
+        setCursor(Qt::UpArrowCursor);
     break;
 
 /*