summaryrefslogtreecommitdiff
path: root/muse2/muse/midiedit
diff options
context:
space:
mode:
authorTim E. Real <termtech@rogers.com>2013-02-20 01:16:45 +0000
committerTim E. Real <termtech@rogers.com>2013-02-20 01:16:45 +0000
commitc3650bf9b2302e1a20853f0cadc7833370e3d0dd (patch)
treefa1a229b0928290a00f974a14104e385d42c5905 /muse2/muse/midiedit
parent612acc2cd3979edf441d2f33403f6b3403c1cf05 (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.cpp430
-rw-r--r--muse2/muse/midiedit/dcanvas.h12
-rw-r--r--muse2/muse/midiedit/dlist.cpp2
-rw-r--r--muse2/muse/midiedit/drumedit.cpp93
-rw-r--r--muse2/muse/midiedit/drumedit.h4
-rw-r--r--muse2/muse/midiedit/drummap.cpp272
-rw-r--r--muse2/muse/midiedit/ecanvas.cpp37
-rw-r--r--muse2/muse/midiedit/ecanvas.h10
-rw-r--r--muse2/muse/midiedit/pianoroll.cpp65
-rw-r--r--muse2/muse/midiedit/pianoroll.h3
-rw-r--r--muse2/muse/midiedit/prcanvas.cpp66
-rw-r--r--muse2/muse/midiedit/prcanvas.h6
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&);