# HG changeset patch # User matthiasm # Date 1371338197 -3600 # Node ID 12d570c27d85f7e26aea6acd69ad56950fc89dcc # Parent f61a54364d1d1b3c933f48fb633a9f8e6683de0b split drag delete diff -r f61a54364d1d -r 12d570c27d85 layer/FlexiNoteLayer.cpp --- 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) diff -r f61a54364d1d -r 12d570c27d85 layer/FlexiNoteLayer.h --- 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 ¬e, 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; diff -r f61a54364d1d -r 12d570c27d85 layer/Layer.h --- 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. diff -r f61a54364d1d -r 12d570c27d85 view/Pane.cpp --- 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; /*