diff options
author | Tim E. Real <termtech@rogers.com> | 2013-02-20 01:16:45 +0000 |
---|---|---|
committer | Tim E. Real <termtech@rogers.com> | 2013-02-20 01:16:45 +0000 |
commit | c3650bf9b2302e1a20853f0cadc7833370e3d0dd (patch) | |
tree | fa1a229b0928290a00f974a14104e385d42c5905 /muse2/muse/midiedit | |
parent | 612acc2cd3979edf441d2f33403f6b3403c1cf05 (diff) |
MASSIVE FIXES: MANY editor, usability, operation fixes and changes.
See ChangeLog.
Diffstat (limited to 'muse2/muse/midiedit')
-rw-r--r-- | muse2/muse/midiedit/dcanvas.cpp | 430 | ||||
-rw-r--r-- | muse2/muse/midiedit/dcanvas.h | 12 | ||||
-rw-r--r-- | muse2/muse/midiedit/dlist.cpp | 2 | ||||
-rw-r--r-- | muse2/muse/midiedit/drumedit.cpp | 93 | ||||
-rw-r--r-- | muse2/muse/midiedit/drumedit.h | 4 | ||||
-rw-r--r-- | muse2/muse/midiedit/drummap.cpp | 272 | ||||
-rw-r--r-- | muse2/muse/midiedit/ecanvas.cpp | 37 | ||||
-rw-r--r-- | muse2/muse/midiedit/ecanvas.h | 10 | ||||
-rw-r--r-- | muse2/muse/midiedit/pianoroll.cpp | 65 | ||||
-rw-r--r-- | muse2/muse/midiedit/pianoroll.h | 3 | ||||
-rw-r--r-- | muse2/muse/midiedit/prcanvas.cpp | 66 | ||||
-rw-r--r-- | muse2/muse/midiedit/prcanvas.h | 6 |
12 files changed, 555 insertions, 445 deletions
diff --git a/muse2/muse/midiedit/dcanvas.cpp b/muse2/muse/midiedit/dcanvas.cpp index 7984d904..c16375d1 100644 --- a/muse2/muse/midiedit/dcanvas.cpp +++ b/muse2/muse/midiedit/dcanvas.cpp @@ -156,7 +156,6 @@ DrumCanvas::DrumCanvas(MidiEditor* pr, QWidget* parent, int sx, DrumCanvas::~DrumCanvas() { - if (must_delete_our_drum_map && ourDrumMap!=NULL) delete [] ourDrumMap; @@ -165,9 +164,60 @@ DrumCanvas::~DrumCanvas() //--------------------------------------------------------- // moveCanvasItems +// Return false if invalid index +//--------------------------------------------------------- + +bool DrumCanvas::index2Note(int index, int* port, int* channel, int* note) +{ + if ((index<0) || (index>=getOurDrumMapSize())) + return false; + + int mport, ch; + if(old_style_drummap_mode) + { + // Default to track port if -1 and track channel if -1. + mport = ourDrumMap[index].port; + if(mport == -1) + { + if(!curPart || !curPart->track() || !curPart->track()->isMidiTrack()) + return false; + MusECore::MidiTrack* mt = static_cast<MusECore::MidiTrack*>(curPart->track()); + mport = mt->outPort(); + } + ch = ourDrumMap[index].channel; + if(ch == -1) + { + if(!curPart || !curPart->track() || !curPart->track()->isMidiTrack()) + return false; + MusECore::MidiTrack* mt = static_cast<MusECore::MidiTrack*>(curPart->track()); + ch = mt->outChannel(); + } + } + else + { + MusECore::Track* track = *instrument_map[index].tracks.begin(); + if(!track->isMidiTrack()) + return false; + MusECore::MidiTrack* mt = static_cast<MusECore::MidiTrack*>(track); + mport = mt->outPort(); + ch = mt->outChannel(); + } + + if(port) + *port = mport; + if(channel) + *channel = ch; + if(note) + *note = old_style_drummap_mode ? ourDrumMap[index].anote : instrument_map[index].pitch; + + return true; +} + +//--------------------------------------------------------- +// moveCanvasItems //--------------------------------------------------------- -MusECore::Undo DrumCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtype) +MusECore::Undo DrumCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtype, bool rasterize) { if(editor->parts()->empty()) @@ -191,7 +241,9 @@ MusECore::Undo DrumCanvas::moveCanvasItems(CItemList& items, int dp, int dx, Dra int x = ci->pos().x() + dx; int y = pitch2y(y2pitch(ci->pos().y()) + dp); - QPoint newpos = raster(QPoint(x, y)); + QPoint newpos = QPoint(x, y); + if(rasterize) + newpos = raster(newpos); // Test moving the item... DEvent* nevent = (DEvent*) ci; @@ -199,7 +251,7 @@ MusECore::Undo DrumCanvas::moveCanvasItems(CItemList& items, int dp, int dx, Dra x = newpos.x(); if(x < 0) x = 0; - int ntick = editor->rasterVal(x) - part->tick(); + int ntick = (rasterize ? editor->rasterVal(x) : x) - part->tick(); if(ntick < 0) ntick = 0; int diff = ntick + event.lenTick() - part->lenTick(); @@ -247,7 +299,9 @@ MusECore::Undo DrumCanvas::moveCanvasItems(CItemList& items, int dp, int dx, Dra int y = ci->pos().y(); int nx = x + dx; int ny = pitch2y(y2pitch(y) + dp); - QPoint newpos = raster(QPoint(nx, ny)); + QPoint newpos = QPoint(nx, ny); + if(rasterize) + newpos = raster(newpos); selectItem(ci, true); iDoneList idl; @@ -259,7 +313,7 @@ MusECore::Undo DrumCanvas::moveCanvasItems(CItemList& items, int dp, int dx, Dra // Do not process if the event has already been processed (meaning it's an event in a clone part)... if (idl == doneList.end()) { - if (moveItem(operations, ci, newpos, dtype) == false) //error? + if (moveItem(operations, ci, newpos, dtype, rasterize) == false) //error? { QMessageBox::warning(this, tr("Moving items failed"), tr("The selection couldn't be moved, because at least one note would be moved into a track which is different from both the original track and the current part's track.\nChanging the current part with ALT+LEFT/RIGHT may help.")); return MusECore::Undo(); //return empty list @@ -295,17 +349,17 @@ MusECore::Undo DrumCanvas::moveCanvasItems(CItemList& items, int dp, int dx, Dra // moveItem //--------------------------------------------------------- -bool DrumCanvas::moveItem(MusECore::Undo& operations, CItem* item, const QPoint& pos, DragType dtype) +bool DrumCanvas::moveItem(MusECore::Undo& operations, CItem* item, const QPoint& pos, DragType dtype, bool rasterize) { DEvent* nevent = (DEvent*) item; MusECore::MidiPart* part = (MusECore::MidiPart*)nevent->part(); MusECore::MidiPart* dest_part = part; - int instrument = y2pitch(pos.y()); + int instrument = y2pitch(pos.y()); if (instrument<0) instrument=0; if (instrument>=getOurDrumMapSize()) instrument=getOurDrumMapSize()-1; - + MusECore::Event event = nevent->event(); if (!instrument_map[instrument].tracks.contains(dest_part->track())) { if (debugMsg) @@ -320,20 +374,15 @@ bool DrumCanvas::moveItem(MusECore::Undo& operations, CItem* item, const QPoint& dest_part=(MusECore::MidiPart*)curPart; } - - MusECore::Event event = nevent->event(); - int x = pos.x(); if (x < 0) x = 0; - int ntick = editor->rasterVal(x) - dest_part->tick(); + int ntick = (rasterize ? editor->rasterVal(x) : x) - dest_part->tick(); if (ntick < 0) ntick = 0; MusECore::Event newEvent = event.clone(); - int ev_pitch = instrument_map[instrument].pitch; - newEvent.setPitch(ev_pitch); newEvent.setTick(ntick); @@ -365,15 +414,26 @@ CItem* DrumCanvas::newItem(const QPoint& p, int state) int instr = y2pitch(p.y()); if ((instr<0) || (instr>=getOurDrumMapSize())) return NULL; + + int k4 = (Qt::MetaModifier | Qt::AltModifier); + //int nk4 = Qt::ControlModifier; + + int k2 = Qt::MetaModifier; + int nk2 = (Qt::ControlModifier | Qt::AltModifier); - int velo = ourDrumMap[instr].lv4; - if (state == Qt::ShiftModifier) - velo = ourDrumMap[instr].lv3; - else if (state == Qt::ControlModifier) + int k1 = (Qt::ControlModifier | Qt::MetaModifier); + int nk1 = Qt::AltModifier; + + int velo = ourDrumMap[instr].lv3; + if ((state & k4) == k4) // && !(state & nk4)) + velo = ourDrumMap[instr].lv4; + else if ((state & k2) == k2 && !(state & nk2)) velo = ourDrumMap[instr].lv2; - else if (state == (Qt::ControlModifier | Qt::ShiftModifier)) + else if ((state & k1) == k1 && !(state & nk1)) velo = ourDrumMap[instr].lv1; - int tick = editor->rasterVal(p.x()); + int tick = p.x(); + if(!(state & Qt::ShiftModifier)) + tick = editor->rasterVal(tick); return newItem(tick, instr, velo); } @@ -407,7 +467,6 @@ CItem* DrumCanvas::newItem(int tick, int instrument, int velocity) tick -= curPart->tick(); if (tick < 0) - //tick=0; return 0; MusECore::Event e(MusECore::Note); e.setTick(tick); @@ -416,55 +475,14 @@ CItem* DrumCanvas::newItem(int tick, int instrument, int velocity) e.setLenTick(ourDrumMap[instrument].len); if(_playEvents) { - int pitch = old_style_drummap_mode ? ourDrumMap[instrument].anote : instrument_map[instrument].pitch; - int port, channel; - if(old_style_drummap_mode) - { - // Default to track port if -1 and track channel if -1. - port = ourDrumMap[instrument].port; - if(port == -1) - { - if(!curPart || !curPart->track() || !curPart->track()->isMidiTrack()) - return 0; - MidiTrack* mt = static_cast<MidiTrack*>(curPart->track()); - port = mt->outPort(); - } - channel = ourDrumMap[instrument].channel; - if(channel == -1) - { - if(!curPart || !curPart->track() || !curPart->track()->isMidiTrack()) - return 0; - MidiTrack* mt = static_cast<MidiTrack*>(curPart->track()); - channel = mt->outChannel(); - } - } - else - { - Track* t = *instrument_map[instrument].tracks.begin(); - if(!t->isMidiTrack()) - return NULL; - MidiTrack* mt = static_cast<MidiTrack*>(t); - port = mt->outPort(); - channel = mt->outChannel(); - } - startPlayEvent(pitch, e.velo(), port, channel); + int pitch, port, channel; + if(index2Note(instrument, &port, &channel, &pitch)) + startPlayEvent(pitch, e.velo(), port, channel); } return new DEvent(e, curPart, instrument); } //--------------------------------------------------------- -// resizeItem -//--------------------------------------------------------- - -void DrumCanvas::resizeItem(CItem* item, bool, bool) - { - DEvent* nevent = (DEvent*) item; - MusECore::Event ev = nevent->event(); - // Indicate do undo, and do not do port controller values and clone parts. - MusEGlobal::audio->msgDeleteEvent(ev, nevent->part(), true, false, false); - } - -//--------------------------------------------------------- // newItem //--------------------------------------------------------- void DrumCanvas::newItem(CItem* item, bool noSnap) { @@ -473,68 +491,66 @@ void DrumCanvas::newItem(CItem* item, bool noSnap) { void DrumCanvas::newItem(CItem* item, bool noSnap, bool replace) { - if (item) + if(!item) { - DEvent* nevent = (DEvent*) item; - MusECore::Event event = nevent->event(); - int x = item->x(); - if (x<0) - x=0; - if (!noSnap) - x = editor->rasterVal(x); - event.setTick(x - nevent->part()->tick()); - int npitch = event.pitch(); - - if(_playEvents) { - //stopPlayEvent(); - keyReleased(pitch2y(event.pitch()), true); // kinda backwards but this should pick the right port, stopPlayEvent does not know. - } + printf("THIS SHOULD NEVER HAPPEN: DrumCanvas::newItem called with NULL item!\n"); + return; + } + + DEvent* nevent = (DEvent*) item; + MusECore::Event event = nevent->event(); + MusECore::Part* part = nevent->part(); + int ptick = part->tick(); + int x = item->x(); + if (x<ptick) + x=ptick; + if (!noSnap) + x = editor->rasterVal(x); + if (x<ptick) + x=ptick; + event.setTick(x - ptick); + int npitch = y2pitch(item->y()); + if ((npitch<0) || (npitch>=getOurDrumMapSize())) + return; + npitch = instrument_map[npitch].pitch; + event.setPitch(npitch); + // check for existing event + // if found change command semantic from insert to delete + MusECore::EventList* el = part->events(); + MusECore::iEvent lower = el->lower_bound(event.tick()); + MusECore::iEvent upper = el->upper_bound(event.tick()); + + for (MusECore::iEvent i = lower; i != upper; ++i) { + MusECore::Event ev = i->second; + if(!ev.isNote()) + continue; + if (ev.pitch() == npitch) { + // Indicate do undo, and do not do port controller values and clone parts. + MusEGlobal::audio->msgDeleteEvent(ev, nevent->part(), true, false, false); + if (replace) + break; + else + return; + } + } - // check for existing event - // if found change command semantic from insert to delete - MusECore::EventList* el = nevent->part()->events(); - MusECore::iEvent lower = el->lower_bound(event.tick()); - MusECore::iEvent upper = el->upper_bound(event.tick()); + MusECore::Undo operations; + int diff = event.endTick()-part->lenTick(); - for (MusECore::iEvent i = lower; i != upper; ++i) { - MusECore::Event ev = i->second; - // Added by T356. Only do notes. - if(!ev.isNote()) - continue; - - if (ev.pitch() == npitch) { - // Indicate do undo, and do not do port controller values and clone parts. - MusEGlobal::audio->msgDeleteEvent(ev, nevent->part(), true, false, false); - if (replace) - break; - else - return; - - } - } + if (! ((diff > 0) && part->hasHiddenEvents()) ) //operation is allowed + { + operations.push_back(MusECore::UndoOp(MusECore::UndoOp::AddEvent,event, part, false, false)); - // Added by T356. - MusECore::Part* part = nevent->part(); - MusECore::Undo operations; - int diff = event.endTick()-part->lenTick(); - - if (! ((diff > 0) && part->hasHiddenEvents()) ) //operation is allowed + if (diff > 0) // part must be extended? { - operations.push_back(MusECore::UndoOp(MusECore::UndoOp::AddEvent,event, part, false, false)); - - if (diff > 0) // part must be extended? - { - schedule_resize_all_same_len_clone_parts(part, event.endTick(), operations); - printf("newItem: extending\n"); - } + schedule_resize_all_same_len_clone_parts(part, event.endTick(), operations); + printf("newItem: extending\n"); } - //else forbid action by not applying it - MusEGlobal::song->applyOperationGroup(operations); - songChanged(SC_EVENT_INSERTED); //this forces an update of the itemlist, which is neccessary - //to remove "forbidden" events from the list again - } - else - printf("THIS SHOULD NEVER HAPPEN: DrumCanvas::newItem called with NULL item!\n"); + } + //else forbid action by not applying it + MusEGlobal::song->applyOperationGroup(operations); + songChanged(SC_EVENT_INSERTED); //this forces an update of the itemlist, which is neccessary + //to remove "forbidden" events from the list again } //--------------------------------------------------------- @@ -557,28 +573,52 @@ void DrumCanvas::itemPressed(const MusEGui::CItem* item) { if (!_playEvents) return; - MusECore::Event e = ((DEvent*)item)->event(); - int pitch = e.pitch(); - - startPlayEvent(pitch, e.velo()); //, port, channel); + int index = e.pitch(); + // play note: + int pitch, port, channel; + if(index2Note(index, &port, &channel, &pitch)) + startPlayEvent(pitch, e.velo(), port, channel); } //--------------------------------------------------------- // itemReleased //--------------------------------------------------------- -void DrumCanvas::itemReleased(const MusEGui::CItem* item, const QPoint&) +void DrumCanvas::itemReleased(const MusEGui::CItem*, const QPoint&) { if (!_playEvents) return; - MusECore::Event e = ((DEvent*)item)->event(); - keyReleased(pitch2y(e.pitch()), true); // kinda backwards but this should pick the right port, stopPlayEvent does not know. - //stopPlayEvent(); + stopPlayEvent(); } //--------------------------------------------------------- +// itemMoved +//--------------------------------------------------------- + +void DrumCanvas::itemMoved(const MusEGui::CItem* item, const QPoint& pos) + { + if(!_playEvents) + return; + int index = y2pitch(pos.y()); + int pitch, port, channel; + if(index2Note(index, &port, &channel, &pitch)) + { + if(_playEvents && (port != playedPitchPort || channel != playedPitchChannel || pitch != playedPitch)) + { + MusECore::Event e = ((DEvent*)item)->event(); + // release note: + stopPlayEvent(); + if (moving.size() <= 1) { // items moving or curItem + // play note: + startPlayEvent(pitch, e.velo(), port, channel); + } + } + } + } + +//--------------------------------------------------------- // drawItem //--------------------------------------------------------- @@ -657,33 +697,6 @@ void DrumCanvas::drawMoving(QPainter& p, const CItem* item, const QRect& rect) p.setPen(Qt::black); p.setBrush(Qt::black); p.drawPolygon(pa); - - int instrument = y2pitch(y); - int pitch = instrument_map[instrument].pitch; - MusECore::Event e = ((DEvent*)item)->event(); - if (pitch != playedPitch && _playEvents) { - keyReleased(playedPitch, true); // kinda backwards but this should pick the right port, stopPlayEvent does not know. - if (moving.size() == 1) { - // Default to track port if -1 and track channel if -1. - int port = old_style_drummap_mode ? ourDrumMap[instrument].port : dynamic_cast<MidiTrack*>(*instrument_map[instrument].tracks.begin())->outPort(); - if(port == -1) - { - if(!curPart || !curPart->track() || !curPart->track()->isMidiTrack()) - return; - MidiTrack* mt = static_cast<MidiTrack*>(curPart->track()); - port = mt->outPort(); - } - int channel = old_style_drummap_mode ? ourDrumMap[instrument].channel : dynamic_cast<MidiTrack*>(*instrument_map[instrument].tracks.begin())->outChannel(); - if(channel == -1) - { - if(!curPart || !curPart->track() || !curPart->track()->isMidiTrack()) - return; - MidiTrack* mt = static_cast<MidiTrack*>(curPart->track()); - channel = mt->outChannel(); - } - startPlayEvent(pitch, e.velo(), port, channel); - } - } } //--------------------------------------------------------- @@ -954,34 +967,15 @@ void DrumCanvas::dragLeaveEvent(QDragLeaveEvent*) void DrumCanvas::keyPressed(int index, int velocity) { - using MusECore::MidiTrack; - if ((index<0) || (index>=getOurDrumMapSize())) return; - // called from DList - play event - // Default to track port if -1 and track channel if -1. - int port = old_style_drummap_mode ? ourDrumMap[index].port : dynamic_cast<MidiTrack*>(*instrument_map[index].tracks.begin())->outPort(); - if(port == -1) - { - if(!curPart || !curPart->track() || !curPart->track()->isMidiTrack()) - return; - MidiTrack* mt = static_cast<MidiTrack*>(curPart->track()); - port = mt->outPort(); - } - int channel = old_style_drummap_mode ? ourDrumMap[index].channel : dynamic_cast<MidiTrack*>(*instrument_map[index].tracks.begin())->outChannel(); - if(channel == -1) - { - if(!curPart || !curPart->track() || !curPart->track()->isMidiTrack()) - return; - MidiTrack* mt = static_cast<MidiTrack*>(curPart->track()); - channel = mt->outChannel(); - } - int pitch = old_style_drummap_mode ? ourDrumMap[index].anote : instrument_map[index].pitch; // play note: if(_playEvents) { - startPlayEvent(pitch,velocity, port, channel); + int pitch, port, channel; + if(index2Note(index, &port, &channel, &pitch)) + startPlayEvent(pitch, velocity, port, channel); } if (_steprec) /* && pos[0] >= start_tick && pos[0] < end_tick [removed by flo93: this is handled in steprec->record] */ @@ -1005,38 +999,21 @@ void DrumCanvas::keyPressed(int index, int velocity) // keyReleased //--------------------------------------------------------- -void DrumCanvas::keyReleased(int index, bool) - { - if ((index<0) || (index>=getOurDrumMapSize())) - return; - - // called from DList - silence playing event - // Default to track port if -1 and track channel if -1. - int port = old_style_drummap_mode ? ourDrumMap[index].port : dynamic_cast<MidiTrack*>(*instrument_map[index].tracks.begin())->outPort(); - if(port == -1) - { - if(!curPart || !curPart->track() || !curPart->track()->isMidiTrack()) - return; - MidiTrack* mt = static_cast<MidiTrack*>(curPart->track()); - port = mt->outPort(); - } - int channel = old_style_drummap_mode ? ourDrumMap[index].channel : dynamic_cast<MidiTrack*>(*instrument_map[index].tracks.begin())->outChannel(); - if(channel == -1) +void DrumCanvas::keyReleased(int, bool) { - if(!curPart || !curPart->track() || !curPart->track()->isMidiTrack()) - return; - MidiTrack* mt = static_cast<MidiTrack*>(curPart->track()); - channel = mt->outChannel(); - } - int pitch = old_style_drummap_mode ? ourDrumMap[index].anote : instrument_map[index].pitch; - // release note: if(_playEvents) { - MusECore::MidiPlayEvent e(0, port, channel, 0x90, pitch, 0); - MusEGlobal::audio->msgPlayMidiEvent(&e); - playedPitch=-1; + // REMOVE Tim. + //int pitch, port, channel; + //if(index2Note(index, &port, &channel, &pitch)) + //{ + // MusECore::MidiPlayEvent e(0, port, channel, 0x90, pitch, 0); + // MusEGlobal::audio->msgPlayMidiEvent(&e); + //} + stopPlayEvent(); } + //playedPitch=-1; } //--------------------------------------------------------- @@ -1363,6 +1340,7 @@ int DrumCanvas::getNextStep(unsigned int pos, int basicStep, int stepSize) //--------------------------------------------------------- // keyPress //--------------------------------------------------------- + void DrumCanvas::keyPress(QKeyEvent* event) { if (_tool == CursorTool) { @@ -1394,10 +1372,10 @@ void DrumCanvas::keyPress(QKeyEvent* event) update(); return; } + // NOTE: The inner NewItem may play the note. But let us not stop the note so shortly after playing it. + // So it is up to the corresponding keyRelease() to stop the note. else if (key == shortcuts[SHRT_ADDNOTE_1].key) { newItem(newItem(cursorPos.x(), cursorPos.y(), ourDrumMap[cursorPos.y()].lv1),false,true); - keyPressed(cursorPos.y(), ourDrumMap[cursorPos.y()].lv1); - keyReleased(cursorPos.y(), false); cursorPos.setX(getNextStep(cursorPos.x(),1, _stepSize)); selectCursorEvent(getEventAtCursorPos()); if (mapx(cursorPos.x()) < 0 || mapx(cursorPos.x()) > width()) @@ -1406,8 +1384,6 @@ void DrumCanvas::keyPress(QKeyEvent* event) } else if (key == shortcuts[SHRT_ADDNOTE_2].key) { newItem(newItem(cursorPos.x(), cursorPos.y(), ourDrumMap[cursorPos.y()].lv2),false,true); - keyPressed(cursorPos.y(), ourDrumMap[cursorPos.y()].lv2); - keyReleased(cursorPos.y(), false); cursorPos.setX(getNextStep(cursorPos.x(),1, _stepSize)); selectCursorEvent(getEventAtCursorPos()); if (mapx(cursorPos.x()) < 0 || mapx(cursorPos.x()) > width()) @@ -1416,8 +1392,6 @@ void DrumCanvas::keyPress(QKeyEvent* event) } else if (key == shortcuts[SHRT_ADDNOTE_3].key) { newItem(newItem(cursorPos.x(), cursorPos.y(), ourDrumMap[cursorPos.y()].lv3),false,true); - keyPressed(cursorPos.y(), ourDrumMap[cursorPos.y()].lv3); - keyReleased(cursorPos.y(), false); cursorPos.setX(getNextStep(cursorPos.x(),1, _stepSize)); selectCursorEvent(getEventAtCursorPos()); if (mapx(cursorPos.x()) < 0 || mapx(cursorPos.x()) > width()) @@ -1426,8 +1400,6 @@ void DrumCanvas::keyPress(QKeyEvent* event) } else if (key == shortcuts[SHRT_ADDNOTE_4].key) { newItem(newItem(cursorPos.x(), cursorPos.y(), ourDrumMap[cursorPos.y()].lv4),false,true); - keyPressed(cursorPos.y(), ourDrumMap[cursorPos.y()].lv4); - keyReleased(cursorPos.y(), false); cursorPos.setX(getNextStep(cursorPos.x(),1, _stepSize)); selectCursorEvent(getEventAtCursorPos()); if (mapx(cursorPos.x()) < 0 || mapx(cursorPos.x()) > width()) @@ -1438,6 +1410,36 @@ void DrumCanvas::keyPress(QKeyEvent* event) EventCanvas::keyPress(event); } +//--------------------------------------------------------- +// keyRelease +//--------------------------------------------------------- + +void DrumCanvas::keyRelease(QKeyEvent* event) +{ + if (_tool == CursorTool) + { + if (_playEvents) + { + int key = event->key(); + if (((QInputEvent*)event)->modifiers() & Qt::ShiftModifier) + key += Qt::SHIFT; + if (((QInputEvent*)event)->modifiers() & Qt::AltModifier) + key += Qt::ALT; + if (((QInputEvent*)event)->modifiers() & Qt::ControlModifier) + key+= Qt::CTRL; + if (key == shortcuts[SHRT_ADDNOTE_1].key || + key == shortcuts[SHRT_ADDNOTE_2].key || + key == shortcuts[SHRT_ADDNOTE_3].key || + key == shortcuts[SHRT_ADDNOTE_4].key) + { + // Must stop note that was played. + stopPlayEvent(); + return; + } + } + } + EventCanvas::keyRelease(event); +} //--------------------------------------------------------- // setTool2 diff --git a/muse2/muse/midiedit/dcanvas.h b/muse2/muse/midiedit/dcanvas.h index fb4a5a96..1a1ee546 100644 --- a/muse2/muse/midiedit/dcanvas.h +++ b/muse2/muse/midiedit/dcanvas.h @@ -32,7 +32,6 @@ #define TH 18 - class QResizeEvent; class QDragEnterEvent; class QDropEvent; @@ -109,20 +108,24 @@ 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 MusECore::Undo moveCanvasItems(CItemList&, int, int, DragType); - virtual bool moveItem(MusECore::Undo&, CItem*, const QPoint&, DragType); + virtual MusECore::Undo moveCanvasItems(CItemList&, int, int, DragType, bool rasterize = true); + virtual bool moveItem(MusECore::Undo&, CItem*, const QPoint&, DragType, bool rasterize = true); virtual CItem* newItem(const QPoint&, int); - virtual void resizeItem(CItem*, bool, bool); + virtual void resizeItem(CItem*, bool, bool) { } // Non-virt width is meaningless, such as drums. virtual void newItem(CItem*, bool); virtual void newItem(CItem*, bool, bool replace ); virtual bool deleteItem(CItem*); virtual void itemPressed(const CItem*); virtual void itemReleased(const CItem*, const QPoint&); + virtual void itemMoved(const CItem*, const QPoint&); CItem* newItem(int tick, int instrument, int velocity); + bool index2Note(int index, int* port, int* channel, int* note); int y2pitch(int y) const; int pitch2y(int pitch) const; + inline int y2height(int) const { return TH; } + inline int yItemOffset() const { return -TH/2; } void startDrag(CItem*, bool copymode); void dragEnterEvent(QDragEnterEvent* event); void dragMoveEvent(QDragMoveEvent*); @@ -163,6 +166,7 @@ class DrumCanvas : public EventCanvas { void cmd(int); virtual void modifySelected(NoteInfo::ValType type, int val, bool delta_mode = true); virtual void keyPress(QKeyEvent* event); + virtual void keyRelease(QKeyEvent* event); MusECore::Event *getEventAtCursorPos(); void selectCursorEvent(MusECore::Event *ev); diff --git a/muse2/muse/midiedit/dlist.cpp b/muse2/muse/midiedit/dlist.cpp index a8555cc9..58345ba9 100644 --- a/muse2/muse/midiedit/dlist.cpp +++ b/muse2/muse/midiedit/dlist.cpp @@ -1359,7 +1359,7 @@ int DList::getSelectedInstrument() { if (currentlySelected == NULL) return -1; - return MusEGlobal::drumInmap[int(currentlySelected->enote)]; + return currentlySelected - ourDrumMap; } diff --git a/muse2/muse/midiedit/drumedit.cpp b/muse2/muse/midiedit/drumedit.cpp index fd28d8ea..7766bb08 100644 --- a/muse2/muse/midiedit/drumedit.cpp +++ b/muse2/muse/midiedit/drumedit.cpp @@ -44,6 +44,7 @@ #include <QRect> #include "drumedit.h" +#include "dcanvas.h" #include "mtscale.h" #include "scrollscale.h" #include "xml.h" @@ -79,7 +80,7 @@ bool DrumEdit::_ignore_hide_init = false; static const int xscale = -10; static const int yscale = 1; -static const int drumeditTools = MusEGui::PointerTool | MusEGui::PencilTool | MusEGui::RubberTool | MusEGui::CursorTool | MusEGui::DrawTool; +static const int drumeditTools = MusEGui::PointerTool | MusEGui::PencilTool | MusEGui::RubberTool | MusEGui::CursorTool | MusEGui::DrawTool | PanTool | ZoomTool; //--------------------------------------------------------- @@ -98,10 +99,10 @@ void DrumEdit::setHeaderWhatsThis() header->setWhatsThis(COL_NOTE, tr("this is the note which is played")); header->setWhatsThis(COL_OUTCHANNEL, tr("override track output channel (hold ctl to affect all rows)")); header->setWhatsThis(COL_OUTPORT, tr("override track output port (hold ctl to affect all rows)")); - header->setWhatsThis(COL_LEVEL1, tr("shift + control key: draw velocity level 1")); - header->setWhatsThis(COL_LEVEL2, tr("control key: draw velocity level 2")); - header->setWhatsThis(COL_LEVEL3, tr("shift key: draw velocity level 3")); - header->setWhatsThis(COL_LEVEL4, tr("draw velocity level 4")); + header->setWhatsThis(COL_LEVEL1, tr("control + meta keys: draw velocity level 1")); + header->setWhatsThis(COL_LEVEL2, tr("meta key: draw velocity level 2")); + header->setWhatsThis(COL_LEVEL3, tr("draw default velocity level 3")); + header->setWhatsThis(COL_LEVEL4, tr("meta + alt keys: draw velocity level 4")); } //--------------------------------------------------------- @@ -120,10 +121,10 @@ void DrumEdit::setHeaderToolTips() header->setToolTip(COL_NOTE, tr("this is the note which is played")); header->setToolTip(COL_OUTCHANNEL, tr("override track output channel (ctl: affect all rows)")); header->setToolTip(COL_OUTPORT, tr("override track output port (ctl: affect all rows)")); - header->setToolTip(COL_LEVEL1, tr("shift + control key: draw velocity level 1")); - header->setToolTip(COL_LEVEL2, tr("control key: draw velocity level 2")); - header->setToolTip(COL_LEVEL3, tr("shift key: draw velocity level 3")); - header->setToolTip(COL_LEVEL4, tr("draw velocity level 4")); + header->setToolTip(COL_LEVEL1, tr("control + meta keys: draw velocity level 1")); + header->setToolTip(COL_LEVEL2, tr("meta key: draw velocity level 2")); + header->setToolTip(COL_LEVEL3, tr("draw default velocity level 3")); + header->setToolTip(COL_LEVEL4, tr("meta + alt keys: draw velocity level 4")); } //--------------------------------------------------------- @@ -433,6 +434,8 @@ DrumEdit::DrumEdit(MusECore::PartList* pl, QWidget* parent, const char* name, un speaker->setFocusPolicy(Qt::NoFocus); tools->addWidget(speaker); + tools->addAction(QWhatsThis::createAction(this)); + tools2 = new MusEGui::EditToolBar(this, drumeditTools); addToolBar(tools2); @@ -507,7 +510,8 @@ DrumEdit::DrumEdit(MusECore::PartList* pl, QWidget* parent, const char* name, un canvas->setCanvasTools(drumeditTools); canvas->setFocus(); connect(canvas, SIGNAL(toolChanged(int)), tools2, SLOT(set(int))); - connect(canvas, SIGNAL(horizontalZoom(bool,int)), SLOT(horizontalZoom(bool,int))); + connect(canvas, SIGNAL(horizontalZoom(bool,const QPoint&)), SLOT(horizontalZoom(bool, const QPoint&))); + connect(canvas, SIGNAL(horizontalZoom(int, const QPoint&)), SLOT(horizontalZoom(int, const QPoint&))); connect(canvas, SIGNAL(ourDrumMapChanged(bool)), SLOT(ourDrumMapChanged(bool))); time->setOrigin(offset, 0); @@ -567,6 +571,8 @@ DrumEdit::DrumEdit(MusECore::PartList* pl, QWidget* parent, const char* name, un connect(dlist, SIGNAL(keyReleased(int, bool)), canvas, SLOT(keyReleased(int, bool))); connect(dlist, SIGNAL(mapChanged(int, int)), canvas, SLOT(mapChanged(int, int))); connect(dlist, SIGNAL(redirectWheelEvent(QWheelEvent*)), canvas, SLOT(redirectedWheelEvent(QWheelEvent*))); + connect(dlist, SIGNAL(curDrumInstrumentChanged(int)), SLOT(setCurDrumInstrument(int))); + connect(dlist, SIGNAL(curDrumInstrumentChanged(int)), canvas, SLOT(setCurDrumInstrument(int))); gridS1->setRowStretch(1, 100); gridS1->setColumnStretch(0, 100); @@ -667,6 +673,40 @@ void DrumEdit::songChanged1(MusECore::SongChangedFlags_t bits) } //--------------------------------------------------------- +// horizontalZoom +//--------------------------------------------------------- + +void DrumEdit::horizontalZoom(bool zoom_in, const QPoint& glob_pos) +{ + int mag = hscroll->mag(); + int zoomlvl = MusEGui::ScrollScale::getQuickZoomLevel(mag); + if(zoom_in) + { + if (zoomlvl < MusEGui::ScrollScale::zoomLevels-1) + zoomlvl++; + } + else + { + if (zoomlvl > 1) + zoomlvl--; + } + int newmag = MusEGui::ScrollScale::convertQuickZoomLevelToMag(zoomlvl); + + QPoint cp = canvas->mapFromGlobal(glob_pos); + QPoint sp = split1->mapFromGlobal(glob_pos); + if(cp.x() >= 0 && cp.x() < canvas->width() && sp.y() >= 0 && sp.y() < split1->height()) + hscroll->setMag(newmag, cp.x()); +} + +void DrumEdit::horizontalZoom(int mag, const QPoint& glob_pos) +{ + QPoint cp = canvas->mapFromGlobal(glob_pos); + QPoint sp = split1->mapFromGlobal(glob_pos); + if(cp.x() >= 0 && cp.x() < canvas->width() && sp.y() >= 0 && sp.y() < split1->height()) + hscroll->setMag(hscroll->mag() + mag, cp.x()); +} + +//--------------------------------------------------------- // updateHScrollRange //--------------------------------------------------------- @@ -944,6 +984,7 @@ void DrumEdit::writeStatus(int level, MusECore::Xml& xml) const header->writeStatus(level, xml); xml.intTag(level, "steprec", canvas->steprec()); xml.intTag(level, "midiin", canvas->midiin()); + xml.intTag(level, "tool", int(canvas->tool())); xml.intTag(level, "playEvents", _playEvents); xml.intTag(level, "xpos", hscroll->pos()); xml.intTag(level, "xmag", hscroll->mag()); @@ -977,6 +1018,11 @@ void DrumEdit::readStatus(MusECore::Xml& xml) canvas->setMidiin(val); midiin->setChecked(val); } + else if (tag == "tool") { + int tool = xml.parseInt(); + canvas->setTool(tool); + tools2->set(tool); + } else if (tag == "ctrledit") { CtrlEdit* ctrl = addCtrl(); ctrl->readStatus(xml); @@ -1340,10 +1386,9 @@ void DrumEdit::setupNewCtrl(CtrlEdit* ctrlEdit) connect(ctrlEdit, SIGNAL(timeChanged(unsigned)), SLOT(setTime(unsigned))); connect(ctrlEdit, SIGNAL(destroyedCtrl(CtrlEdit*)), SLOT(removeCtrl(CtrlEdit*))); connect(ctrlEdit, SIGNAL(yposChanged(int)), toolbar, SLOT(setInt(int))); + connect(ctrlEdit, SIGNAL(redirectWheelEvent(QWheelEvent*)), canvas, SLOT(redirectedWheelEvent(QWheelEvent*))); connect(tools2, SIGNAL(toolChanged(int)), ctrlEdit, SLOT(setTool(int))); - connect(dlist, SIGNAL(curDrumInstrumentChanged(int)), SLOT(setCurDrumInstrument(int))); - connect(dlist, SIGNAL(curDrumInstrumentChanged(int)), canvas, SLOT(setCurDrumInstrument(int))); - connect(canvas, SIGNAL(curPartHasChanged(MusECore::Part*)), ctrlEdit, SLOT(curPartHasChanged(MusECore::Part*))); + connect(canvas, SIGNAL(curPartHasChanged(MusECore::Part*)), ctrlEdit, SLOT(curPartHasChanged(MusECore::Part*))); setCurDrumInstrument(dlist->getSelectedInstrument()); @@ -1519,22 +1564,20 @@ void DrumEdit::keyPressEvent(QKeyEvent* event) tools2->set(MusEGui::CursorTool); return; } + else if (key == shortcuts[SHRT_TOOL_PAN].key) { + tools2->set(MusEGui::PanTool); + return; + } + else if (key == shortcuts[SHRT_TOOL_ZOOM].key) { + tools2->set(MusEGui::ZoomTool); + return; + } else if (key == shortcuts[SHRT_ZOOM_IN].key) { - int offset = 0; - QPoint cp = canvas->mapFromGlobal(QCursor::pos()); - QPoint sp = split1->mapFromGlobal(QCursor::pos()); - if(cp.x() >= 0 && cp.x() < canvas->width() && sp.y() >= 0 && sp.y() < split1->height()) - offset = cp.x(); - horizontalZoom(true, offset); + horizontalZoom(true, QCursor::pos()); return; } else if (key == shortcuts[SHRT_ZOOM_OUT].key) { - int offset = 0; - QPoint cp = canvas->mapFromGlobal(QCursor::pos()); - QPoint sp = split1->mapFromGlobal(QCursor::pos()); - if(cp.x() >= 0 && cp.x() < canvas->width() && sp.y() >= 0 && sp.y() < split1->height()) - offset = cp.x(); - horizontalZoom(false, offset); + horizontalZoom(false, QCursor::pos()); return; } else if (key == shortcuts[SHRT_SCROLL_LEFT].key) { diff --git a/muse2/muse/midiedit/drumedit.h b/muse2/muse/midiedit/drumedit.h index 2daafd30..fef06bfe 100644 --- a/muse2/muse/midiedit/drumedit.h +++ b/muse2/muse/midiedit/drumedit.h @@ -48,7 +48,7 @@ class QToolButton; class QWidget; class QComboBox; class QPushButton; - +class QPoint; namespace MusECore { class MidiPart; @@ -177,6 +177,8 @@ class DrumEdit : public MidiEditor { void execUserScript(int); void focusCanvas(); void ourDrumMapChanged(bool); + void horizontalZoom(bool zoom_in, const QPoint& glob_pos); + void horizontalZoom(int mag, const QPoint& glob_pos); virtual void updateHScrollRange(); signals: diff --git a/muse2/muse/midiedit/drummap.cpp b/muse2/muse/midiedit/drummap.cpp index 6853a3e5..9b5ae8dc 100644 --- a/muse2/muse/midiedit/drummap.cpp +++ b/muse2/muse/midiedit/drummap.cpp @@ -42,7 +42,7 @@ namespace MusECore { //--------------------------------------------------------- // Default to track port if -1 and track channel if -1. (These used to say 9, 0 for chan, port). -const DrumMap blankdm = { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 127, 127, false }; +const DrumMap blankdm = { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 127, 127, false }; // this map should have 128 entries, as it's used for initalising iNewDrumMap as well. // iNewDrumMap only has 128 entries. also, the every "out-note" ("anote") should be @@ -52,141 +52,141 @@ const DrumMap blankdm = { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 12 // iNewDrumMap[ idrumMap[i].anote ] = idrumMap[i] // if you ever want to change this, you will need to fix the initNewDrumMap() function. const DrumMap idrumMap[DRUM_MAPSIZE] = { - { QString("Acoustic Bass Drum"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 35, 35, false }, - { QString("Bass Drum 1"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 36, 36, false }, - { QString("Side Stick"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 37, 37, false }, - { QString("Acoustic Snare"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 38, 38, false }, - { QString("Hand Clap"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 39, 39, false }, - { QString("Electric Snare"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 40, 40, false }, - { QString("Low Floor Tom"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 41, 41, false }, - { QString("Closed Hi-Hat"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 42, 42, false }, - { QString("High Floor Tom"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 43, 43, false }, - { QString("Pedal Hi-Hat"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 44, 44, false }, - { QString("Low Tom"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 45, 45, false }, - { QString("Open Hi-Hat"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 46, 46, false }, - { QString("Low-Mid Tom"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 47, 47, false }, - { QString("Hi-Mid Tom"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 48, 48, false }, - { QString("Crash Cymbal 1"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 49, 49, false }, - { QString("High Tom"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 50, 50, false }, - - { QString("Ride Cymbal 1"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 51, 51, false }, - { QString("Chinese Cymbal"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 52, 52, false }, - { QString("Ride Bell"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 53, 53, false }, - { QString("Tambourine"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 54, 54, false }, - { QString("Splash Cymbal"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 55, 55, false }, - { QString("Cowbell"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 56, 56, false }, - { QString("Crash Cymbal 2"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 57, 57, false }, - { QString("Vibraslap"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 58, 58, false }, - { QString("Ride Cymbal 2"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 59, 59, false }, - { QString("Hi Bongo"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 60, 60, false }, - { QString("Low Bongo"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 61, 61, false }, - { QString("Mute Hi Conga"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 62, 62, false }, - { QString("Open Hi Conga"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 63, 63, false }, - { QString("Low Conga"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 64, 64, false }, - { QString("High Timbale"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 65, 65, false }, - { QString("Low Timbale"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 66, 66, false }, - - { QString("High Agogo"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 67, 67, false }, - { QString("Low Agogo"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 68, 68, false }, - { QString("Cabasa"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 69, 69, false }, - { QString("Maracas"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 70, 70, false }, - { QString("Short Whistle"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 71, 71, false }, - { QString("Long Whistle"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 72, 72, false }, - { QString("Short Guiro"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 73, 73, false }, - { QString("Long Guiro"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 74, 74, false }, - { QString("Claves"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 75, 75, false }, - { QString("Hi Wood Block"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 76, 76, false }, - { QString("Low Wood Block"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 77, 77, false }, - { QString("Mute Cuica"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 78, 78, false }, - { QString("Open Cuica"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 79, 79, false }, - { QString("Mute Triangle"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 80, 80, false }, - { QString("Open Triangle"), 100, 16, 32, -1, -1, 70, 90, 127, 110, 81, 81, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 82, 82, false }, - - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 83, 83, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 84, 84, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 85, 85, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 86, 86, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 87, 87, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 88, 88, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 89, 89, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 90, 90, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 91, 91, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 92, 92, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 93, 93, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 94, 94, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 95, 95, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 96, 96, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 97, 97, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 98, 98, false }, - - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 99, 99, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 100, 100, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 101, 101, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 102, 102, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 103, 103, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 104, 104, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 105, 105, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 106, 106, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 107, 107, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 108, 108, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 109, 109, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 110, 110, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 111, 111, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 112, 112, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 113, 113, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 114, 114, false }, - - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 115, 115, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 116, 116, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 117, 117, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 118, 118, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 119, 119, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 120, 120, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 121, 121, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 122, 122, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 123, 123, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 124, 124, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 125, 125, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 126, 126, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 127, 127, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 0, 0, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 1, 1, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 2, 2, false }, - - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 3, 3, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 4, 4, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 5, 5, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 6, 6, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 7, 7, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 8, 8, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 9, 9, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 10, 10, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 11, 11, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 12, 12, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 13, 13, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 14, 14, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 15, 15, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 16, 16, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 17, 17, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 18, 18, false }, - - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 19, 19, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 20, 20, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 21, 21, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 22, 22, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 23, 23, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 24, 24, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 25, 25, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 26, 26, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 27, 27, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 28, 28, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 29, 29, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 30, 30, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 31, 31, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 32, 32, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 33, 33, false }, - { QString(""), 100, 16, 32, -1, -1, 70, 90, 127, 110, 34, 34, false } + { QString("Acoustic Bass Drum"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 35, 35, false }, + { QString("Bass Drum 1"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 36, 36, false }, + { QString("Side Stick"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 37, 37, false }, + { QString("Acoustic Snare"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 38, 38, false }, + { QString("Hand Clap"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 39, 39, false }, + { QString("Electric Snare"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 40, 40, false }, + { QString("Low Floor Tom"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 41, 41, false }, + { QString("Closed Hi-Hat"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 42, 42, false }, + { QString("High Floor Tom"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 43, 43, false }, + { QString("Pedal Hi-Hat"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 44, 44, false }, + { QString("Low Tom"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 45, 45, false }, + { QString("Open Hi-Hat"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 46, 46, false }, + { QString("Low-Mid Tom"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 47, 47, false }, + { QString("Hi-Mid Tom"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 48, 48, false }, + { QString("Crash Cymbal 1"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 49, 49, false }, + { QString("High Tom"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 50, 50, false }, + + { QString("Ride Cymbal 1"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 51, 51, false }, + { QString("Chinese Cymbal"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 52, 52, false }, + { QString("Ride Bell"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 53, 53, false }, + { QString("Tambourine"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 54, 54, false }, + { QString("Splash Cymbal"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 55, 55, false }, + { QString("Cowbell"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 56, 56, false }, + { QString("Crash Cymbal 2"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 57, 57, false }, + { QString("Vibraslap"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 58, 58, false }, + { QString("Ride Cymbal 2"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 59, 59, false }, + { QString("Hi Bongo"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 60, 60, false }, + { QString("Low Bongo"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 61, 61, false }, + { QString("Mute Hi Conga"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 62, 62, false }, + { QString("Open Hi Conga"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 63, 63, false }, + { QString("Low Conga"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 64, 64, false }, + { QString("High Timbale"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 65, 65, false }, + { QString("Low Timbale"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 66, 66, false }, + + { QString("High Agogo"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 67, 67, false }, + { QString("Low Agogo"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 68, 68, false }, + { QString("Cabasa"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 69, 69, false }, + { QString("Maracas"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 70, 70, false }, + { QString("Short Whistle"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 71, 71, false }, + { QString("Long Whistle"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 72, 72, false }, + { QString("Short Guiro"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 73, 73, false }, + { QString("Long Guiro"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 74, 74, false }, + { QString("Claves"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 75, 75, false }, + { QString("Hi Wood Block"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 76, 76, false }, + { QString("Low Wood Block"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 77, 77, false }, + { QString("Mute Cuica"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 78, 78, false }, + { QString("Open Cuica"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 79, 79, false }, + { QString("Mute Triangle"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 80, 80, false }, + { QString("Open Triangle"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 81, 81, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 82, 82, false }, + + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 83, 83, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 84, 84, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 85, 85, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 86, 86, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 87, 87, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 88, 88, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 89, 89, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 90, 90, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 91, 91, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 92, 92, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 93, 93, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 94, 94, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 95, 95, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 96, 96, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 97, 97, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 98, 98, false }, + + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 99, 99, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 100, 100, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 101, 101, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 102, 102, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 103, 103, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 104, 104, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 105, 105, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 106, 106, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 107, 107, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 108, 108, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 109, 109, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 110, 110, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 111, 111, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 112, 112, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 113, 113, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 114, 114, false }, + + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 115, 115, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 116, 116, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 117, 117, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 118, 118, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 119, 119, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 120, 120, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 121, 121, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 122, 122, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 123, 123, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 124, 124, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 125, 125, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 126, 126, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 127, 127, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 0, 0, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 1, 1, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 2, 2, false }, + + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 3, 3, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 4, 4, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 5, 5, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 6, 6, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 7, 7, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 8, 8, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 9, 9, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 10, 10, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 11, 11, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 12, 12, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 13, 13, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 14, 14, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 15, 15, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 16, 16, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 17, 17, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 18, 18, false }, + + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 19, 19, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 20, 20, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 21, 21, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 22, 22, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 23, 23, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 24, 24, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 25, 25, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 26, 26, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 27, 27, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 28, 28, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 29, 29, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 30, 30, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 31, 31, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 32, 32, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 33, 33, false }, + { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 34, 34, false } }; DrumMap iNewDrumMap[128]; diff --git a/muse2/muse/midiedit/ecanvas.cpp b/muse2/muse/midiedit/ecanvas.cpp index e07fc99e..d2456283 100644 --- a/muse2/muse/midiedit/ecanvas.cpp +++ b/muse2/muse/midiedit/ecanvas.cpp @@ -43,6 +43,7 @@ #include "shortcuts.h" #include "audio.h" #include "functions.h" +#include "midi.h" namespace MusEGui { @@ -61,6 +62,10 @@ EventCanvas::EventCanvas(MidiEditor* pr, QWidget* parent, int sx, _playEvents = true; _setCurPartIfOnlyOneEventIsSelected = true; curVelo = 70; + playedPitch = -1; + playedPitchChannel = -1; + playedPitchPort = -1; + playedVelocity = 0; setBg(Qt::white); setAcceptDrops(true); @@ -71,6 +76,12 @@ EventCanvas::EventCanvas(MidiEditor* pr, QWidget* parent, int sx, curPartId = curPart->sn(); } +EventCanvas::~EventCanvas() +{ + if(_playEvents) + stopPlayEvent(); +} + //--------------------------------------------------------- // getCaption //--------------------------------------------------------- @@ -452,7 +463,7 @@ void EventCanvas::viewDropEvent(QDropEvent* event) // 2 move only vertical //--------------------------------------------------------- -void EventCanvas::endMoveItems(const QPoint& pos, DragType dragtype, int dir) +void EventCanvas::endMoveItems(const QPoint& pos, DragType dragtype, int dir, bool rasterize) { int dp = y2pitch(pos.y()) - y2pitch(Canvas::start.y()); int dx = pos.x() - Canvas::start.x(); @@ -464,7 +475,7 @@ void EventCanvas::endMoveItems(const QPoint& pos, DragType dragtype, int dir) - MusECore::Undo operations = moveCanvasItems(moving, dp, dx, dragtype); + MusECore::Undo operations = moveCanvasItems(moving, dp, dx, dragtype, rasterize); if (operations.empty()) songChanged(SC_EVENT_MODIFIED); //this is a hack to force the canvas to repopulate //itself. otherwise, if a moving operation was forbidden, @@ -485,10 +496,17 @@ void EventCanvas::startPlayEvent(int note, int velocity, int port, int channel) { if (MusEGlobal::debugMsg) printf("EventCanvas::startPlayEvent %d %d %d %d\n", note, velocity, port, channel); - playedPitch = note + track()->transposition; + // Release any current note. + stopPlayEvent(); + + playedPitch = note + track()->transposition; + playedVelocity = velocity; + playedPitchPort = port; + playedPitchChannel = channel; + // play note: - MusECore::MidiPlayEvent e(0, port, channel, 0x90, playedPitch, velocity); + MusECore::MidiPlayEvent e(0, port, channel, MusECore::ME_NOTEON, playedPitch, velocity); MusEGlobal::audio->msgPlayMidiEvent(&e); } @@ -505,13 +523,14 @@ void EventCanvas::startPlayEvent(int note, int velocity) void EventCanvas::stopPlayEvent() { - int port = track()->outPort(); - int channel = track()->outChannel(); - + if(playedPitch == -1 || playedPitchPort == -1 || playedPitchChannel == -1) + return; // release note: - MusECore::MidiPlayEvent ev(0, port, channel, 0x90, playedPitch, 0); + //MusECore::MidiPlayEvent ev(0, playedPitchPort, playedPitchChannel, 0x90, playedPitch, 0); // REMOVE Tim. + MusECore::MidiPlayEvent ev(0, playedPitchPort, playedPitchChannel, MusECore::ME_NOTEOFF, playedPitch, playedVelocity); MusEGlobal::audio->msgPlayMidiEvent(&ev); - playedPitch = -1; + playedPitch = playedPitchPort = playedPitchChannel = -1; + playedVelocity = 0; } } // namespace MusEGui diff --git a/muse2/muse/midiedit/ecanvas.h b/muse2/muse/midiedit/ecanvas.h index b5120173..95e856c8 100644 --- a/muse2/muse/midiedit/ecanvas.h +++ b/muse2/muse/midiedit/ecanvas.h @@ -68,6 +68,9 @@ class EventCanvas : public Canvas { protected: int playedPitch; + int playedVelocity; + int playedPitchPort; + int playedPitchChannel; bool _playEvents; MidiEditor* editor; unsigned start_tick, end_tick; @@ -79,9 +82,9 @@ class EventCanvas : public Canvas { void updateSelection(); virtual CItem* addItem(MusECore::Part*, MusECore::Event&) = 0; virtual QPoint raster(const QPoint&) const; - virtual MusECore::Undo moveCanvasItems(CItemList&, int, int, DragType) = 0; - virtual bool moveItem(MusECore::Undo&, CItem*, const QPoint&, DragType) = 0; - virtual void endMoveItems(const QPoint&, DragType, int dir); + virtual MusECore::Undo moveCanvasItems(CItemList&, int, int, DragType, bool rasterize = true) = 0; + virtual bool moveItem(MusECore::Undo&, CItem*, const QPoint&, DragType, bool rasterize = true) = 0; + virtual void endMoveItems(const QPoint&, DragType, int dir, bool rasterize = true); virtual void startPlayEvent(int note, int velocity); virtual void startPlayEvent(int note, int velocity, int port, int channel); virtual void stopPlayEvent(); @@ -101,6 +104,7 @@ class EventCanvas : public Canvas { public: EventCanvas(MidiEditor*, QWidget*, int, int, const char* name = 0); + virtual ~EventCanvas(); MusECore::MidiTrack* track() const; virtual unsigned start() const { return start_tick; } virtual unsigned end() const { return end_tick; } diff --git a/muse2/muse/midiedit/pianoroll.cpp b/muse2/muse/midiedit/pianoroll.cpp index 9fc835a1..66e6c2fb 100644 --- a/muse2/muse/midiedit/pianoroll.cpp +++ b/muse2/muse/midiedit/pianoroll.cpp @@ -30,6 +30,7 @@ #include <QMenu> #include <QSignalMapper> #include <QMenuBar> +#include <QWhatsThis> #include <QApplication> #include <QClipboard> #include <QDir> @@ -84,7 +85,7 @@ int PianoRoll::colorModeInit = 0; static const int xscale = -10; static const int yscale = 1; static const int pianoWidth = 40; -static int pianorollTools = MusEGui::PointerTool | MusEGui::PencilTool | MusEGui::RubberTool | MusEGui::DrawTool; +static int pianorollTools = MusEGui::PointerTool | MusEGui::PencilTool | MusEGui::RubberTool | MusEGui::DrawTool | PanTool | ZoomTool; //--------------------------------------------------------- @@ -300,6 +301,8 @@ PianoRoll::PianoRoll(MusECore::PartList* pl, QWidget* parent, const char* name, speaker->setFocusPolicy(Qt::NoFocus); tools->addWidget(speaker); + tools->addAction(QWhatsThis::createAction(this)); + tools2 = new MusEGui::EditToolBar(this, pianorollTools); addToolBar(tools2); @@ -375,7 +378,8 @@ PianoRoll::PianoRoll(MusECore::PartList* pl, QWidget* parent, const char* name, canvas->setCanvasTools(pianorollTools); canvas->setFocus(); connect(canvas, SIGNAL(toolChanged(int)), tools2, SLOT(set(int))); - connect(canvas, SIGNAL(horizontalZoom(bool,int)), SLOT(horizontalZoom(bool,int))); + connect(canvas, SIGNAL(horizontalZoom(bool, const QPoint&)), SLOT(horizontalZoom(bool, const QPoint&))); + connect(canvas, SIGNAL(horizontalZoom(int, const QPoint&)), SLOT(horizontalZoom(int, const QPoint&))); time->setOrigin(offset, 0); gridS1->setRowStretch(2, 100); @@ -526,6 +530,40 @@ void PianoRoll::configChanged() } //--------------------------------------------------------- +// horizontalZoom +//--------------------------------------------------------- + +void PianoRoll::horizontalZoom(bool zoom_in, const QPoint& glob_pos) +{ + int mag = hscroll->mag(); + int zoomlvl = MusEGui::ScrollScale::getQuickZoomLevel(mag); + if(zoom_in) + { + if (zoomlvl < MusEGui::ScrollScale::zoomLevels-1) + zoomlvl++; + } + else + { + if (zoomlvl > 1) + zoomlvl--; + } + int newmag = MusEGui::ScrollScale::convertQuickZoomLevelToMag(zoomlvl); + + QPoint cp = canvas->mapFromGlobal(glob_pos); + QPoint sp = splitter->mapFromGlobal(glob_pos); + if(cp.x() >= 0 && cp.x() < canvas->width() && sp.y() >= 0 && sp.y() < splitter->height()) + hscroll->setMag(newmag, cp.x()); +} + +void PianoRoll::horizontalZoom(int mag, const QPoint& glob_pos) +{ + QPoint cp = canvas->mapFromGlobal(glob_pos); + QPoint sp = splitter->mapFromGlobal(glob_pos); + if(cp.x() >= 0 && cp.x() < canvas->width() && sp.y() >= 0 && sp.y() < splitter->height()) + hscroll->setMag(hscroll->mag() + mag, cp.x()); +} + +//--------------------------------------------------------- // updateHScrollRange //--------------------------------------------------------- @@ -895,6 +933,7 @@ void PianoRoll::setupNewCtrl(CtrlEdit* ctrlEdit) connect(ctrlEdit, SIGNAL(timeChanged(unsigned)), SLOT(setTime(unsigned))); connect(ctrlEdit, SIGNAL(destroyedCtrl(CtrlEdit*)), SLOT(removeCtrl(CtrlEdit*))); connect(ctrlEdit, SIGNAL(yposChanged(int)), toolbar, SLOT(setInt(int))); + connect(ctrlEdit, SIGNAL(redirectWheelEvent(QWheelEvent*)), canvas, SLOT(redirectedWheelEvent(QWheelEvent*))); connect(piano, SIGNAL(curSelectedPitchChanged(int)), SLOT(setCurDrumInstrument(int))); //connect(piano, SIGNAL(curSelectedPitchChanged(int)), canvas, SLOT(setCurDrumInstrument(int))); @@ -1164,6 +1203,14 @@ void PianoRoll::keyPressEvent(QKeyEvent* event) tools2->set(MusEGui::DrawTool); return; } + else if (key == shortcuts[SHRT_TOOL_PAN].key) { + tools2->set(MusEGui::PanTool); + return; + } + else if (key == shortcuts[SHRT_TOOL_ZOOM].key) { + tools2->set(MusEGui::ZoomTool); + return; + } else if (key == shortcuts[SHRT_INSTRUMENT_STEP_UP].key) { piano->setCurSelectedPitch(piano->curSelectedPitch()+1); MusEGlobal::song->update(SC_DRUMMAP); @@ -1200,21 +1247,11 @@ void PianoRoll::keyPressEvent(QKeyEvent* event) return; } else if (key == shortcuts[SHRT_ZOOM_IN].key) { - int offset = 0; - QPoint cp = canvas->mapFromGlobal(QCursor::pos()); - QPoint sp = splitter->mapFromGlobal(QCursor::pos()); - if(cp.x() >= 0 && cp.x() < canvas->width() && sp.y() >= 0 && sp.y() < splitter->height()) - offset = cp.x(); - horizontalZoom(true, offset); + horizontalZoom(true, QCursor::pos()); return; } else if (key == shortcuts[SHRT_ZOOM_OUT].key) { - int offset = 0; - QPoint cp = canvas->mapFromGlobal(QCursor::pos()); - QPoint sp = splitter->mapFromGlobal(QCursor::pos()); - if(cp.x() >= 0 && cp.x() < canvas->width() && sp.y() >= 0 && sp.y() < splitter->height()) - offset = cp.x(); - horizontalZoom(false, offset); + horizontalZoom(false, QCursor::pos()); return; } else if (key == shortcuts[SHRT_GOTO_CPOS].key) { diff --git a/muse2/muse/midiedit/pianoroll.h b/muse2/muse/midiedit/pianoroll.h index 65af30a8..00572030 100644 --- a/muse2/muse/midiedit/pianoroll.h +++ b/muse2/muse/midiedit/pianoroll.h @@ -47,6 +47,7 @@ class QScrollBar; class QToolBar; class QToolButton; class QWidget; +class QPoint; namespace MusECore { class MidiPart; @@ -184,6 +185,8 @@ class PianoRoll : public MidiEditor { void isDeleting(MusEGui::TopWin*); public slots: + void horizontalZoom(bool zoom_in, const QPoint& glob_pos); + void horizontalZoom(int mag, const QPoint& glob_pos); virtual void updateHScrollRange(); void execDeliveredScript(int id); void execUserScript(int id); diff --git a/muse2/muse/midiedit/prcanvas.cpp b/muse2/muse/midiedit/prcanvas.cpp index 0670625a..83c20a1a 100644 --- a/muse2/muse/midiedit/prcanvas.cpp +++ b/muse2/muse/midiedit/prcanvas.cpp @@ -98,7 +98,6 @@ PianoCanvas::PianoCanvas(MidiEditor* pr, QWidget* parent, int sx, int sy) : EventCanvas(pr, parent, sx, sy) { colorMode = 0; - playedPitch = -1; for (int i=0;i<128;i++) noteHeldDown[i]=false; steprec=new MusECore::StepRec(noteHeldDown); @@ -298,7 +297,7 @@ void PianoCanvas::viewMouseDoubleClickEvent(QMouseEvent* event) // moveCanvasItems //--------------------------------------------------------- -MusECore::Undo PianoCanvas::moveCanvasItems(MusEGui::CItemList& items, int dp, int dx, DragType dtype) +MusECore::Undo PianoCanvas::moveCanvasItems(MusEGui::CItemList& items, int dp, int dx, DragType dtype, bool rasterize) { if(editor->parts()->empty()) return MusECore::Undo(); //return empty list @@ -321,7 +320,9 @@ MusECore::Undo PianoCanvas::moveCanvasItems(MusEGui::CItemList& items, int dp, i int x = ci->pos().x() + dx; int y = pitch2y(y2pitch(ci->pos().y()) + dp); - QPoint newpos = raster(QPoint(x, y)); + QPoint newpos = QPoint(x, y); + if(rasterize) + newpos = raster(newpos); // Test moving the item... NEvent* nevent = (NEvent*) ci; @@ -329,7 +330,7 @@ MusECore::Undo PianoCanvas::moveCanvasItems(MusEGui::CItemList& items, int dp, i x = newpos.x(); if(x < 0) x = 0; - int ntick = editor->rasterVal(x) - part->tick(); + int ntick = (rasterize ? editor->rasterVal(x) : x) - part->tick(); if(ntick < 0) ntick = 0; int diff = ntick + event.lenTick() - part->lenTick(); @@ -377,7 +378,9 @@ MusECore::Undo PianoCanvas::moveCanvasItems(MusEGui::CItemList& items, int dp, i int y = ci->pos().y(); int nx = x + dx; int ny = pitch2y(y2pitch(y) + dp); - QPoint newpos = raster(QPoint(nx, ny)); + QPoint newpos = QPoint(nx, ny); + if(rasterize) + newpos = raster(newpos); selectItem(ci, true); iDoneList idl; @@ -389,7 +392,7 @@ MusECore::Undo PianoCanvas::moveCanvasItems(MusEGui::CItemList& items, int dp, i // Do not process if the event has already been processed (meaning it's an event in a clone part)... if (idl == doneList.end()) { - moveItem(operations, ci, newpos, dtype); // always returns true. if not, change is necessary here! + moveItem(operations, ci, newpos, dtype, rasterize); // always returns true. if not, change is necessary here! doneList.push_back(ci); } ci->move(newpos); @@ -422,7 +425,7 @@ MusECore::Undo PianoCanvas::moveCanvasItems(MusEGui::CItemList& items, int dp, i // called after moving an object //--------------------------------------------------------- -bool PianoCanvas::moveItem(MusECore::Undo& operations, MusEGui::CItem* item, const QPoint& pos, DragType dtype) +bool PianoCanvas::moveItem(MusECore::Undo& operations, MusEGui::CItem* item, const QPoint& pos, DragType dtype, bool rasterize) { NEvent* nevent = (NEvent*) item; MusECore::Event event = nevent->event(); @@ -431,17 +434,10 @@ bool PianoCanvas::moveItem(MusECore::Undo& operations, MusEGui::CItem* item, con int x = pos.x(); if (x < 0) x = 0; - if (event.pitch() != npitch && _playEvents) { - stopPlayEvent(); - if (moving.size() == 1) { - startPlayEvent(npitch, event.velo()); - } - } - MusECore::Part* part = nevent->part(); newEvent.setPitch(npitch); - int ntick = editor->rasterVal(x) - part->tick(); + int ntick = (rasterize ? editor->rasterVal(x) : x) - part->tick(); if (ntick < 0) ntick = 0; newEvent.setTick(ntick); @@ -463,10 +459,12 @@ bool PianoCanvas::moveItem(MusECore::Undo& operations, MusEGui::CItem* item, con // newItem(p, state) //--------------------------------------------------------- -MusEGui::CItem* PianoCanvas::newItem(const QPoint& p, int) +MusEGui::CItem* PianoCanvas::newItem(const QPoint& p, int state) { int pitch = y2pitch(p.y()); - int tick = editor->rasterVal1(p.x()); + int tick = p.x(); + if(!(state & Qt::ShiftModifier)) + tick = editor->rasterVal1(tick); int len = p.x() - tick; tick -= curPart->tick(); if (tick < 0) @@ -486,25 +484,25 @@ MusEGui::CItem* PianoCanvas::newItem(const QPoint& p, int) void PianoCanvas::newItem(MusEGui::CItem* item, bool noSnap) { - if(_playEvents) - stopPlayEvent(); - NEvent* nevent = (NEvent*) item; MusECore::Event event = nevent->event(); + MusECore::Part* part = nevent->part(); + int ptick = part->tick(); int x = item->x(); - if (x<0) - x=0; + if (x<ptick) + x=ptick; + if(!noSnap) + x = editor->rasterVal1(x); //round down + if (x<ptick) + x=ptick; int w = item->width(); - - if (!noSnap) { - x = editor->rasterVal1(x); //round down - w = editor->rasterVal(x + w) - x; - if (w == 0) - w = editor->raster(); - } - MusECore::Part* part = nevent->part(); - event.setTick(x - part->tick()); + event.setTick(x - ptick); + if (!noSnap) + w = editor->rasterVal(w); + if (w == 0) + w = editor->rasterStep(ptick); event.setLenTick(w); + event.setPitch(y2pitch(item->y())); MusECore::Undo operations; @@ -693,9 +691,7 @@ void PianoCanvas::pianoPressed(int pitch, int velocity, bool shift) { // play note: if(_playEvents) - { startPlayEvent(pitch, velocity); - } if (_steprec && curPart) // && pos[0] >= start_tick && pos[0] < end_tick [removed by flo93: this is handled in steprec->record] steprec->record(curPart,pitch,editor->raster(),editor->raster(),velocity,MusEGlobal::globalKeyState&Qt::ControlModifier,shift, -1 /* anything which is != rcSteprecNote */); @@ -968,11 +964,9 @@ void PianoCanvas::itemMoved(const MusEGui::CItem* item, const QPoint& pos) if ((playedPitch != -1) && (playedPitch != npitch)) { NEvent* nevent = (NEvent*) item; MusECore::Event event = nevent->event(); - // release note: stopPlayEvent(); - - if (moving.size() == 1) { // items moving + if (moving.size() <= 1) { // items moving or curItem // play note: startPlayEvent(npitch, event.velo()); } diff --git a/muse2/muse/midiedit/prcanvas.h b/muse2/muse/midiedit/prcanvas.h index 0dfe806c..888427ea 100644 --- a/muse2/muse/midiedit/prcanvas.h +++ b/muse2/muse/midiedit/prcanvas.h @@ -70,8 +70,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 MusECore::Undo moveCanvasItems(CItemList&, int, int, DragType); - virtual bool moveItem(MusECore::Undo&, CItem*, const QPoint&, DragType); + virtual MusECore::Undo moveCanvasItems(CItemList&, int, int, DragType, bool rasterize = true); + virtual bool moveItem(MusECore::Undo&, CItem*, const QPoint&, DragType, bool rasterize = true); virtual CItem* newItem(const QPoint&, int); virtual void resizeItem(CItem*, bool noSnap, bool); virtual void newItem(CItem*, bool noSnap); @@ -84,6 +84,8 @@ class PianoCanvas : public EventCanvas { int y2pitch(int) const; int pitch2y(int) const; + inline int y2height(int) const { return KH/2; } + inline int yItemOffset() const { return KH/4; } virtual void drawCanvas(QPainter&, const QRect&); virtual void itemPressed(const CItem*); virtual void itemReleased(const CItem*, const QPoint&); |