diff options
author | Florian Jung <flo@windfisch.org> | 2011-05-22 13:26:40 +0000 |
---|---|---|
committer | Florian Jung <flo@windfisch.org> | 2011-05-22 13:26:40 +0000 |
commit | 8fbfa07b464210054a177b1e92f47b5f2744d1cc (patch) | |
tree | fb8c2d49db90f51744251380a7b8d77689341282 /muse2/muse/midiedit | |
parent | 14f8a08279d9266467d457707166b439fd080fa2 (diff) |
moving events in canvases and reordering the drum map have
been speeded up by using operation groups.
HOWEVER: there might be bugs, in fact, i may even have messed
up the whole thing!
use with CAUTION and TEST intensively!
Diffstat (limited to 'muse2/muse/midiedit')
-rw-r--r-- | muse2/muse/midiedit/dcanvas.cpp | 56 | ||||
-rw-r--r-- | muse2/muse/midiedit/dcanvas.h | 6 | ||||
-rw-r--r-- | muse2/muse/midiedit/ecanvas.cpp | 45 | ||||
-rw-r--r-- | muse2/muse/midiedit/ecanvas.h | 9 | ||||
-rw-r--r-- | muse2/muse/midiedit/prcanvas.cpp | 94 | ||||
-rw-r--r-- | muse2/muse/midiedit/prcanvas.h | 6 |
6 files changed, 93 insertions, 123 deletions
diff --git a/muse2/muse/midiedit/dcanvas.cpp b/muse2/muse/midiedit/dcanvas.cpp index a7e33bd1..a61b5001 100644 --- a/muse2/muse/midiedit/dcanvas.cpp +++ b/muse2/muse/midiedit/dcanvas.cpp @@ -95,12 +95,13 @@ DrumCanvas::DrumCanvas(MidiEditor* pr, QWidget* parent, int sx, // moveCanvasItems //--------------------------------------------------------- -void DrumCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtype, int* pflags) +Undo DrumCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtype, int* pflags) { if(editor->parts()->empty()) - return; + return Undo(); //return empty list PartsToChangeMap parts2change; + Undo operations; int modified = 0; for(iPart ip = editor->parts()->begin(); ip != editor->parts()->end(); ++ip) @@ -173,8 +174,8 @@ void DrumCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtyp } editor->parts()->add(newPart); - // Indicate no undo, and do port controller values but not clone parts. - audio->msgChangePart(opart, newPart, false, true, false); + // Do port controller values but not clone parts. + operations.push_back(UndoOp(UndoOp::ModifyPart, opart, newPart, true, false)); ip2c->second.npart = newPart; @@ -214,20 +215,12 @@ void DrumCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtyp break; // Do not process if the event has already been processed (meaning it's an event in a clone part)... - if(idl != doneList.end()) - // Just move the canvas item. - ci->move(newpos); - else + if (idl == doneList.end()) { - // Currently moveItem always returns true. - if(moveItem(ci, newpos, dtype)) - { - // Add the canvas item to the list of done items. - doneList.push_back(ci); - // Move the canvas item. - ci->move(newpos); - } + operations.push_back(moveItem(ci, newpos, dtype)); + doneList.push_back(ci); } + ci->move(newpos); if(moving.size() == 1) { itemReleased(curItem, newpos); @@ -238,13 +231,15 @@ void DrumCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtyp if(pflags) *pflags = modified; + + return operations; } //--------------------------------------------------------- // moveItem //--------------------------------------------------------- -bool DrumCanvas::moveItem(CItem* item, const QPoint& pos, DragType dtype) +UndoOp DrumCanvas::moveItem(CItem* item, const QPoint& pos, DragType dtype) { DEvent* nevent = (DEvent*) item; @@ -271,16 +266,10 @@ bool DrumCanvas::moveItem(CItem* item, const QPoint& pos, DragType dtype) if(((int)newEvent.endTick() - (int)part->lenTick()) > 0) printf("DrumCanvas::moveItem Error! New event end:%d exceeds length:%d of part:%s\n", newEvent.endTick(), part->lenTick(), part->name().toLatin1().constData()); - if (dtype == MOVE_COPY || dtype == MOVE_CLONE) { - // Indicate no undo, and do not do port controller values and clone parts. - audio->msgAddEvent(newEvent, part, false, false, false); - } - else { - // Indicate no undo, and do not do port controller values and clone parts. - audio->msgChangeEvent(event, newEvent, part, false, false, false); - } - - return true; + if (dtype == MOVE_COPY || dtype == MOVE_CLONE) + return UndoOp(UndoOp::AddEvent, newEvent, part, false, false); + else + return UndoOp(UndoOp::ModifyEvent, newEvent, event, part, false, false); } //--------------------------------------------------------- @@ -387,7 +376,6 @@ void DrumCanvas::newItem(CItem* item, bool noSnap, bool replace) // Indicate no undo, and do not do port controller values and clone parts. audio->msgAddEvent(event, part, false, false, false); song->endUndo(modified); - } //--------------------------------------------------------- @@ -836,7 +824,8 @@ void DrumCanvas::mapChanged(int spitch, int dpitch) // If start/stopundo is there, undo misbehaves since it doesn't undo but messes things up // Other solution: implement a specific undo-event for this (SC_DRUMMAP_MODIFIED or something) which undoes movement of // dlist-items (ml) - + + Undo operations; std::vector< std::pair<Part*, Event*> > delete_events; std::vector< std::pair<Part*, Event> > add_events; @@ -891,12 +880,10 @@ void DrumCanvas::mapChanged(int spitch, int dpitch) } } - song->startUndo(); for (idel_ev i = delete_events.begin(); i != delete_events.end(); i++) { Part* thePart = (*i).first; Event* theEvent = (*i).second; - // Indicate no undo, and do port controller values but not clone parts. - audio->msgDeleteEvent(*theEvent, thePart, false, true, false); + operations.push_back(UndoOp(UndoOp::DeleteEvent, *theEvent, thePart, true, false)); } DrumMap dm = drumMap[spitch]; @@ -910,11 +897,10 @@ void DrumCanvas::mapChanged(int spitch, int dpitch) for (iadd_ev i = add_events.begin(); i != add_events.end(); i++) { Part* thePart = (*i).first; Event& theEvent = (*i).second; - // Indicate no undo, and do port controller values but not clone parts. - audio->msgAddEvent(theEvent, thePart, false, true, false); + operations.push_back(UndoOp(UndoOp::AddEvent, theEvent, thePart, true, false)); } - song->endUndo(SC_EVENT_MODIFIED); + song->applyOperationGroup(operations); song->update(SC_DRUMMAP); } diff --git a/muse2/muse/midiedit/dcanvas.h b/muse2/muse/midiedit/dcanvas.h index b86bc2d7..748dd74f 100644 --- a/muse2/muse/midiedit/dcanvas.h +++ b/muse2/muse/midiedit/dcanvas.h @@ -50,10 +50,8 @@ class DrumCanvas : public EventCanvas { virtual void drawItem(QPainter&, const CItem*, const QRect&); void drawTopItem(QPainter& p, const QRect& rect); virtual void drawMoving(QPainter&, const CItem*, const QRect&); - virtual void moveCanvasItems(CItemList&, int, int, DragType, int*); - // Changed by T356. - //virtual bool moveItem(CItem*, const QPoint&, DragType, int*); - virtual bool moveItem(CItem*, const QPoint&, DragType); + virtual Undo moveCanvasItems(CItemList&, int, int, DragType, int*); + virtual UndoOp moveItem(CItem*, const QPoint&, DragType); virtual CItem* newItem(const QPoint&, int); virtual void resizeItem(CItem*, bool); virtual void newItem(CItem*, bool); diff --git a/muse2/muse/midiedit/ecanvas.cpp b/muse2/muse/midiedit/ecanvas.cpp index 7a421411..e084c212 100644 --- a/muse2/muse/midiedit/ecanvas.cpp +++ b/muse2/muse/midiedit/ecanvas.cpp @@ -101,21 +101,12 @@ QPoint EventCanvas::raster(const QPoint& p) const } //--------------------------------------------------------- -// startUndo +// update //--------------------------------------------------------- -void EventCanvas::startUndo(DragType) +void EventCanvas::updateSong(DragType dtype, int flags) { - song->startUndo(); - } - -//--------------------------------------------------------- -// endUndo -//--------------------------------------------------------- - -void EventCanvas::endUndo(DragType dtype, int flags) - { - song->endUndo(flags | ((dtype == MOVE_COPY || dtype == MOVE_CLONE) + song->update(flags | ((dtype == MOVE_COPY || dtype == MOVE_CLONE) ? SC_EVENT_INSERTED : SC_EVENT_MODIFIED)); } @@ -545,3 +536,33 @@ void EventCanvas::viewDropEvent(QDropEvent* event) } } + +//--------------------------------------------------------- +// endMoveItems +// dir = 0 move in all directions +// 1 move only horizontal +// 2 move only vertical +//--------------------------------------------------------- + +void EventCanvas::endMoveItems(const QPoint& pos, DragType dragtype, int dir) + { + int dp = y2pitch(pos.y()) - y2pitch(Canvas::start.y()); + int dx = pos.x() - Canvas::start.x(); + + if (dir == 1) + dp = 0; + else if (dir == 2) + dx = 0; + + + + int modified = 0; + + Undo operations = moveCanvasItems(moving, dp, dx, dragtype, &modified); + song->applyOperationGroup(operations); + updateSong(dragtype, modified); + + moving.clear(); + updateSelection(); + redraw(); + } diff --git a/muse2/muse/midiedit/ecanvas.h b/muse2/muse/midiedit/ecanvas.h index 86e1c200..23875598 100644 --- a/muse2/muse/midiedit/ecanvas.h +++ b/muse2/muse/midiedit/ecanvas.h @@ -38,12 +38,7 @@ class EventCanvas : public Canvas { Q_OBJECT virtual void leaveEvent(QEvent*e); virtual void enterEvent(QEvent*e); - // Removed by T356. - //virtual QPoint raster(const QPoint&) const; - virtual void startUndo(DragType); - - virtual void endUndo(DragType, int flags = 0); virtual void mouseMove(QMouseEvent* event); protected: @@ -58,6 +53,10 @@ class EventCanvas : public Canvas { virtual void addItem(Part*, Event&) = 0; // Added by T356. virtual QPoint raster(const QPoint&) const; + virtual Undo moveCanvasItems(CItemList&, int, int, DragType, int*) = 0; + virtual UndoOp moveItem(CItem*, const QPoint&, DragType) = 0; + virtual void endMoveItems(const QPoint&, DragType, int dir); + virtual void updateSong(DragType, int flags = 0); public slots: void redrawGrid() { redraw(); } diff --git a/muse2/muse/midiedit/prcanvas.cpp b/muse2/muse/midiedit/prcanvas.cpp index a38e0ee1..6845bd12 100644 --- a/muse2/muse/midiedit/prcanvas.cpp +++ b/muse2/muse/midiedit/prcanvas.cpp @@ -34,6 +34,7 @@ #include "cmd.h" #include "song.h" #include "audio.h" +#include "functions.h" #define CHORD_TIMEOUT 75 @@ -257,11 +258,12 @@ void PianoCanvas::viewMouseDoubleClickEvent(QMouseEvent* event) // moveCanvasItems //--------------------------------------------------------- -void PianoCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtype, int* pflags) +Undo PianoCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtype, int* pflags) { if(editor->parts()->empty()) - return; - + return Undo(); //return empty list + + Undo operations; PartsToChangeMap parts2change; int modified = 0; @@ -335,8 +337,8 @@ void PianoCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dty } editor->parts()->add(newPart); - // Indicate no undo, and do port controller values but not clone parts. - audio->msgChangePart(opart, newPart, false, true, false); + // Do port controller values but not clone parts. + operations.push_back(UndoOp(UndoOp::ModifyPart, opart, newPart, true, false)); ip2c->second.npart = newPart; @@ -352,6 +354,7 @@ void PianoCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dty std::vector< CItem* > doneList; typedef std::vector< CItem* >::iterator iDoneList; + for(iCItem ici = items.begin(); ici != items.end(); ++ici) { CItem* ci = ici->second; @@ -376,21 +379,12 @@ void PianoCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dty break; // Do not process if the event has already been processed (meaning it's an event in a clone part)... - //if(moveItem(ci, newpos, dtype)) - if(idl != doneList.end()) - // Just move the canvas item. - ci->move(newpos); - else + if (idl == doneList.end()) { - // Currently moveItem always returns true. - if(moveItem(ci, newpos, dtype)) - { - // Add the canvas item to the list of done items. - doneList.push_back(ci); - // Move the canvas item. - ci->move(newpos); - } + operations.push_back(moveItem(ci, newpos, dtype)); + doneList.push_back(ci); } + ci->move(newpos); if(moving.size() == 1) itemReleased(curItem, newpos); @@ -400,6 +394,8 @@ void PianoCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dty if(pflags) *pflags = modified; + + return operations; } //--------------------------------------------------------- @@ -407,9 +403,7 @@ void PianoCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dty // called after moving an object //--------------------------------------------------------- -// Changed by T356. -//bool PianoCanvas::moveItem(CItem* item, const QPoint& pos, DragType dtype, int* pflags) -bool PianoCanvas::moveItem(CItem* item, const QPoint& pos, DragType dtype) +UndoOp PianoCanvas::moveItem(CItem* item, const QPoint& pos, DragType dtype) { NEvent* nevent = (NEvent*) item; Event event = nevent->event(); @@ -430,7 +424,7 @@ bool PianoCanvas::moveItem(CItem* item, const QPoint& pos, DragType dtype) // Changed by T356. Part* part = nevent->part(); // - //Part * part = Canvas::part(); // part can be dynamically recreated, ask the authority + //Part* part = Canvas::part(); // part can be dynamically recreated, ask the authority newEvent.setPitch(npitch); int ntick = editor->rasterVal(x) - part->tick(); @@ -446,12 +440,9 @@ bool PianoCanvas::moveItem(CItem* item, const QPoint& pos, DragType dtype) printf("PianoCanvas::moveItem Error! New event end:%d exceeds length:%d of part:%s\n", newEvent.endTick(), part->lenTick(), part->name().toLatin1().constData()); if (dtype == MOVE_COPY || dtype == MOVE_CLONE) - audio->msgAddEvent(newEvent, part, false, false, false); + return UndoOp(UndoOp::AddEvent, newEvent, part, false, false); else - audio->msgChangeEvent(event, newEvent, part, false, false, false); - //song->endUndo(modified); - - return true; + return UndoOp(UndoOp::ModifyEvent, newEvent, event, part, false, false); } //--------------------------------------------------------- @@ -509,7 +500,6 @@ void PianoCanvas::newItem(CItem* item, bool noSnap) part = newPart; // reassign } // Indicate no undo, and do not do port controller values and clone parts. - //audio->msgAddEvent(event, part,false); audio->msgAddEvent(event, part, false, false, false); song->endUndo(modified); } @@ -623,8 +613,9 @@ void PianoCanvas::pianoCmd(int cmd) if (part == 0) break; - song->startUndo(); + EventList* el = part->events(); + Undo operations; std::list <Event> elist; for (iEvent e = el->lower_bound(pos[0] - part->tick()); e != el->end(); ++e) @@ -633,10 +624,11 @@ void PianoCanvas::pianoCmd(int cmd) Event event = *i; Event newEvent = event.clone(); newEvent.setTick(event.tick() + editor->raster());// - part->tick()); - // Indicate no undo, and do not do port controller values and clone parts. - audio->msgChangeEvent(event, newEvent, part, false, false, false); + // Do not do port controller values and clone parts. + operations.push_back(UndoOp(UndoOp::ModifyEvent, newEvent, event, part, false, false)); } - song->endUndo(SC_EVENT_MODIFIED); + song->applyOperationGroup(operations); + Pos p(editor->rasterVal(pos[0] + editor->rasterStep(pos[0])), true); song->setPos(0, p, true, false, true); } @@ -648,7 +640,8 @@ void PianoCanvas::pianoCmd(int cmd) MidiPart* part = (MidiPart*)curPart; if (part == 0) break; - song->startUndo(); + + Undo operations; EventList* el = part->events(); std::list<Event> elist; @@ -658,10 +651,10 @@ void PianoCanvas::pianoCmd(int cmd) Event event = *i; Event newEvent = event.clone(); newEvent.setTick(event.tick() - editor->raster() - part->tick()); - // Indicate no undo, and do not do port controller values and clone parts. - audio->msgChangeEvent(event, newEvent, part, false, false, false); + // Do not do port controller values and clone parts. + operations.push_back(UndoOp(UndoOp::ModifyEvent, newEvent, event, part, false, false)); } - song->endUndo(SC_EVENT_MODIFIED); + song->applyOperationGroup(operations); Pos p(editor->rasterVal(pos[0] - editor->rasterStep(pos[0])), true); song->setPos(0, p, true, false, true); } @@ -811,16 +804,7 @@ void PianoCanvas::cmd(int cmd) switch (cmd) { case CMD_CUT: copy(); - song->startUndo(); - for (iCItem i = items.begin(); i != items.end(); ++i) { - if (!(i->second->isSelected())) - continue; - NEvent* e = (NEvent*)(i->second); - Event ev = e->event(); - // Indicate no undo, and do not do port controller values and clone parts. - audio->msgDeleteEvent(ev, e->part(), false, false, false); - } - song->endUndo(SC_EVENT_REMOVED); + erase_notes(partlist_to_set(editor->parts()),1); //FINDMICH is this correct? or must i do this on current_part? break; case CMD_COPY: copy(); @@ -903,23 +887,7 @@ void PianoCanvas::cmd(int cmd) } break; - case CMD_FIXED_LEN: //Set notes to the length specified in the drummap - if (!selectionSize()) - break; - song->startUndo(); - for (iCItem k = items.begin(); k != items.end(); ++k) { - if (k->second->isSelected()) { - NEvent* nevent = (NEvent*)(k->second); - Event event = nevent->event(); - Event newEvent = event.clone(); - newEvent.setLenTick(editor->raster()); - // Indicate no undo, and do not do port controller values and clone parts. - audio->msgChangeEvent(event, newEvent, nevent->part(), false, false, false); - } - } - song->endUndo(SC_EVENT_MODIFIED); - break; - + case CMD_FIXED_LEN: case CMD_CRESCENDO: case CMD_TRANSPOSE: case CMD_THIN_OUT: diff --git a/muse2/muse/midiedit/prcanvas.h b/muse2/muse/midiedit/prcanvas.h index a04ca514..94827354 100644 --- a/muse2/muse/midiedit/prcanvas.h +++ b/muse2/muse/midiedit/prcanvas.h @@ -49,10 +49,8 @@ class PianoCanvas : public EventCanvas { virtual void drawItem(QPainter&, const CItem*, const QRect&); void drawTopItem(QPainter &p, const QRect &rect); virtual void drawMoving(QPainter&, const CItem*, const QRect&); - virtual void moveCanvasItems(CItemList&, int, int, DragType, int*); - // Changed by T356. - //virtual bool moveItem(CItem*, const QPoint&, DragType, int*); - virtual bool moveItem(CItem*, const QPoint&, DragType); + virtual Undo moveCanvasItems(CItemList&, int, int, DragType, int*); + virtual UndoOp moveItem(CItem*, const QPoint&, DragType); virtual CItem* newItem(const QPoint&, int); virtual void resizeItem(CItem*, bool noSnap); virtual void newItem(CItem*, bool noSnap); |