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 | |
parent | 612acc2cd3979edf441d2f33403f6b3403c1cf05 (diff) |
MASSIVE FIXES: MANY editor, usability, operation fixes and changes.
See ChangeLog.
Diffstat (limited to 'muse2/muse')
55 files changed, 1650 insertions, 1070 deletions
diff --git a/muse2/muse/arranger/arranger.cpp b/muse2/muse/arranger/arranger.cpp index 90a7e8f3..e5f22daf 100644 --- a/muse2/muse/arranger/arranger.cpp +++ b/muse2/muse/arranger/arranger.cpp @@ -24,6 +24,7 @@ #include <stdio.h> #include <limits.h> +#include <math.h> #include <QComboBox> #include <QGridLayout> @@ -77,6 +78,10 @@ namespace MusEGui { std::vector<Arranger::custom_col_t> Arranger::custom_columns; //FINDMICH TODO: eliminate all usage of new_custom_columns std::vector<Arranger::custom_col_t> Arranger::new_custom_columns; //and instead let the arranger update without restarting muse! QByteArray Arranger::header_state; +static const char* gArrangerRasterStrings[] = { + QT_TRANSLATE_NOOP("MusEGui::Arranger", "Off"), QT_TRANSLATE_NOOP("MusEGui::Arranger", "Bar"), "1/2", "1/4", "1/8", "1/16" + }; +static int gArrangerRasterTable[] = { 1, 0, 768, 384, 192, 96 }; void Arranger::writeCustomColumns(int level, MusECore::Xml& xml) { @@ -238,22 +243,19 @@ Arranger::Arranger(ArrangerView* parent, const char* name) cursorPos->setFixedHeight(22); toolbar->addWidget(cursorPos); - const char* rastval[] = { - QT_TRANSLATE_NOOP("MusEGui::Arranger", "Off"), QT_TRANSLATE_NOOP("MusEGui::Arranger", "Bar"), "1/2", "1/4", "1/8", "1/16" - }; label = new QLabel(tr("Snap")); label->setAlignment(Qt::AlignRight|Qt::AlignVCenter); label->setIndent(3); toolbar->addWidget(label); - QComboBox* raster = new QComboBox(); + _rasterCombo = new QComboBox(); for (int i = 0; i < 6; i++) - raster->insertItem(i, tr(rastval[i])); - raster->setCurrentIndex(1); + _rasterCombo->insertItem(i, tr(gArrangerRasterStrings[i]), gArrangerRasterTable[i]); + _rasterCombo->setCurrentIndex(1); // Set the audio record part snapping. Set to 0 (bar), the same as this combo box intial raster. MusEGlobal::song->setArrangerRaster(0); - toolbar->addWidget(raster); - connect(raster, SIGNAL(activated(int)), SLOT(_setRaster(int))); - raster->setFocusPolicy(Qt::TabFocus); + toolbar->addWidget(_rasterCombo); + connect(_rasterCombo, SIGNAL(activated(int)), SLOT(rasterChanged(int))); + _rasterCombo->setFocusPolicy(Qt::TabFocus); // Song len label = new QLabel(tr("Len")); @@ -477,7 +479,8 @@ Arranger::Arranger(ArrangerView* parent, const char* name) connect(list, SIGNAL(keyPressExt(QKeyEvent*)), canvas, SLOT(redirKeypress(QKeyEvent*))); connect(canvas, SIGNAL(selectTrackAbove()), list, SLOT(selectTrackAbove())); connect(canvas, SIGNAL(selectTrackBelow()), list, SLOT(selectTrackBelow())); - 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(lenEntry, SIGNAL(returnPressed()), SLOT(focusCanvas())); connect(lenEntry, SIGNAL(escapePressed()), SLOT(focusCanvas())); connect(globalPitchSpinBox, SIGNAL(returnPressed()), SLOT(focusCanvas())); @@ -732,6 +735,7 @@ void Arranger::trackSelectionChanged() void Arranger::writeStatus(int level, MusECore::Xml& xml) { xml.tag(level++, "arranger"); + xml.intTag(level, "raster", _raster); xml.intTag(level, "info", ib->isChecked()); split->writeStatus(level, xml); @@ -785,6 +789,7 @@ void Arranger::readConfiguration(MusECore::Xml& xml) void Arranger::readStatus(MusECore::Xml& xml) { + int rast = -1; for (;;) { MusECore::Xml::Token token(xml.parse()); const QString& tag(xml.s1()); @@ -793,7 +798,9 @@ void Arranger::readStatus(MusECore::Xml& xml) case MusECore::Xml::End: return; case MusECore::Xml::TagStart: - if (tag == "info") + if (tag == "raster") + rast = xml.parseInt(); + else if (tag == "info") showTrackinfoFlag = xml.parseInt(); else if (tag == split->objectName()) split->readStatus(xml); @@ -811,6 +818,8 @@ void Arranger::readStatus(MusECore::Xml& xml) case MusECore::Xml::TagEnd: if (tag == "arranger") { ib->setChecked(showTrackinfoFlag); + if(rast != -1) + setRasterVal(rast); return; } default: @@ -820,15 +829,12 @@ void Arranger::readStatus(MusECore::Xml& xml) } //--------------------------------------------------------- -// setRaster +// rasterChanged //--------------------------------------------------------- -void Arranger::_setRaster(int index) +void Arranger::rasterChanged(int index) { - static int rasterTable[] = { - 1, 0, 768, 384, 192, 96 - }; - _raster = rasterTable[index]; + _raster = gArrangerRasterTable[index]; // Set the audio record part snapping. MusEGlobal::song->setArrangerRaster(_raster); canvas->redraw(); @@ -836,6 +842,30 @@ void Arranger::_setRaster(int index) } //--------------------------------------------------------- +// setRasterVal +//--------------------------------------------------------- + +bool Arranger::setRasterVal(int val) +{ + if(_raster == val) + return true; + int idx = _rasterCombo->findData(val); + if(idx == -1) + { + fprintf(stderr, "Arranger::setRasterVal raster:%d not found\n", val); + return false; + } + _raster = val; + _rasterCombo->blockSignals(true); + _rasterCombo->setCurrentIndex(idx); + _rasterCombo->blockSignals(false); + // Set the audio record part snapping. + MusEGlobal::song->setArrangerRaster(_raster); + canvas->redraw(); + return true; +} + +//--------------------------------------------------------- // reset //--------------------------------------------------------- @@ -1207,28 +1237,18 @@ void Arranger::keyPressEvent(QKeyEvent* event) key+= Qt::CTRL; if (key == shortcuts[SHRT_ZOOM_IN].key) { - int offset = 0; - QPoint cp = canvas->mapFromGlobal(QCursor::pos()); - QPoint sp = editor->mapFromGlobal(QCursor::pos()); - if(cp.x() >= 0 && cp.x() < canvas->width() && sp.y() >= 0 && sp.y() < editor->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 = editor->mapFromGlobal(QCursor::pos()); - if(cp.x() >= 0 && cp.x() < canvas->width() && sp.y() >= 0 && sp.y() < editor->height()) - offset = cp.x(); - horizontalZoom(false, offset); + horizontalZoom(false, QCursor::pos()); return; } QWidget::keyPressEvent(event); } -void Arranger::horizontalZoom(bool zoom_in, int pos_offset) +void Arranger::horizontalZoom(bool zoom_in, const QPoint& glob_pos) { int mag = hscroll->mag(); int zoomlvl = ScrollScale::getQuickZoomLevel(mag); @@ -1243,7 +1263,19 @@ void Arranger::horizontalZoom(bool zoom_in, int pos_offset) zoomlvl--; } int newmag = ScrollScale::convertQuickZoomLevelToMag(zoomlvl); - hscroll->setMag(newmag, pos_offset); + + QPoint cp = canvas->mapFromGlobal(glob_pos); + QPoint sp = editor->mapFromGlobal(glob_pos); + if(cp.x() >= 0 && cp.x() < canvas->width() && sp.y() >= 0 && sp.y() < editor->height()) + hscroll->setMag(newmag, cp.x()); +} + +void Arranger::horizontalZoom(int mag, const QPoint& glob_pos) +{ + QPoint cp = canvas->mapFromGlobal(glob_pos); + QPoint sp = editor->mapFromGlobal(glob_pos); + if(cp.x() >= 0 && cp.x() < canvas->width() && sp.y() >= 0 && sp.y() < editor->height()) + hscroll->setMag(hscroll->mag() + mag, cp.x()); } } // namespace MusEGui diff --git a/muse2/muse/arranger/arranger.h b/muse2/muse/arranger/arranger.h index e56a187d..9b58f097 100644 --- a/muse2/muse/arranger/arranger.h +++ b/muse2/muse/arranger/arranger.h @@ -41,6 +41,8 @@ class QMenu; class QToolButton; class QWheelEvent; class QKeyEvent; +class QPoint; +class QComboBox; namespace MusECore { class Track; @@ -118,6 +120,7 @@ class Arranger : public QWidget { ArrangerView* _parentWin; QWidget* editor; int _quant, _raster; + QComboBox* _rasterCombo; PartCanvas* canvas; ScrollScale* hscroll; QScrollBar* vscroll; @@ -153,7 +156,7 @@ class Arranger : public QWidget { void setHeaderWhatsThis(); private slots: - void _setRaster(int); + void rasterChanged(int); void songlenChanged(int); void showTrackInfo(bool); void trackSelectionChanged(); @@ -166,7 +169,8 @@ class Arranger : public QWidget { void setTempo100(); void setTempo200(); void verticalScrollSetYpos(unsigned); - void horizontalZoom(bool zoom_in, int pos_offset); + void horizontalZoom(bool zoom_in, const QPoint& glob_pos); + void horizontalZoom(int mag, const QPoint& glob_pos); signals: void editPart(MusECore::Track*); @@ -235,6 +239,8 @@ class Arranger : public QWidget { unsigned cursorValue() { return cursVal; } ArrangerView* parentWin() const { return _parentWin; } + + bool setRasterVal(int); }; } // namespace MusEGui diff --git a/muse2/muse/arranger/pcanvas.cpp b/muse2/muse/arranger/pcanvas.cpp index 88b613aa..72c03263 100644 --- a/muse2/muse/arranger/pcanvas.cpp +++ b/muse2/muse/arranger/pcanvas.cpp @@ -36,6 +36,7 @@ #include <QMessageBox> #include <QUrl> #include <QPoint> +#include <QIcon> #include "fastlog.h" #include "widgets/tools.h" @@ -55,6 +56,7 @@ #include "functions.h" #include "filedialog.h" #include "marker/marker.h" +#include "menutitleitem.h" #include "mpevent.h" #include "midievent.h" #include "midi.h" @@ -125,7 +127,7 @@ int PartCanvas::y2pitch(int y) const MusECore::TrackList* tl = MusEGlobal::song->tracks(); int yy = 0; int idx = 0; - for (MusECore::iTrack it = tl->begin(); it != tl->end(); ++it, ++idx) { + for (MusECore::ciTrack it = tl->begin(); it != tl->end(); ++it, ++idx) { int h = (*it)->height(); if (y < yy+h) break; @@ -143,7 +145,7 @@ int PartCanvas::pitch2y(int p) const MusECore::TrackList* tl = MusEGlobal::song->tracks(); int yy = 0; int idx = 0; - for (MusECore::iTrack it = tl->begin(); it != tl->end(); ++it, ++idx) { + for (MusECore::ciTrack it = tl->begin(); it != tl->end(); ++it, ++idx) { if (idx == p) break; yy += (*it)->height(); @@ -152,6 +154,23 @@ int PartCanvas::pitch2y(int p) const } //--------------------------------------------------------- +// y2height +//--------------------------------------------------------- + +int PartCanvas::y2height(int y) const +{ + MusECore::TrackList* tl = MusEGlobal::song->tracks(); + int yy = 0; + for (MusECore::ciTrack it = tl->begin(); it != tl->end(); ++it) { + int h = (*it)->height(); + if (y < yy+h) + return h; + yy += h; + } + return 20; +} + +//--------------------------------------------------------- // leaveEvent //--------------------------------------------------------- @@ -223,7 +242,7 @@ void PartCanvas::viewMouseDoubleClickEvent(QMouseEvent* event) else { MusECore::TrackList* tl = MusEGlobal::song->tracks(); - MusECore::iTrack it; + MusECore::ciTrack it; int yy = 0; int y = event->y(); for (it = tl->begin(); it != tl->end(); ++it) { @@ -276,7 +295,7 @@ void PartCanvas::updateSong(DragType t, MusECore::SongChangedFlags_t flags) // moveCanvasItems //--------------------------------------------------------- -void PartCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtype) +void PartCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtype, bool rasterize) { MusECore::Undo operations; @@ -284,18 +303,13 @@ void PartCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtyp { CItem* ci = ici->second; - // DELETETHIS 5 - // If this item's part is in the parts2change list, change the item's part to the new part. - //MusECore::Part* pt = ci->part(); - //iP2C ip2c = parts2change.find(pt); - //if(ip2c != parts2change.end()) - // ci->setPart(ip2c->second); - int x = ci->pos().x(); 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); bool result=moveItem(operations, ci, newpos, dtype); @@ -450,11 +464,11 @@ void PartCanvas::partsChanged() curItem=NULL; items.clearDelete(); - for (MusECore::iTrack t = tracks->begin(); t != tracks->end(); ++t) { + for (MusECore::ciTrack t = tracks->begin(); t != tracks->end(); ++t) { if ((*t)->isVisible()) //ignore parts from hidden tracks { MusECore::PartList* pl = (*t)->parts(); - for (MusECore::iPart i = pl->begin(); i != pl->end(); ++i) { + for (MusECore::ciPart i = pl->begin(); i != pl->end(); ++i) { MusECore::Part* part = i->second; NPart* np = new NPart(part); items.add(np); @@ -509,7 +523,7 @@ void PartCanvas::resizeItem(CItem* i, bool noSnap, bool ctrl) MusECore::Part* p = ((NPart*)(i))->part(); int pos = p->tick() + i->width(); - int snappedpos = p->tick(); + int snappedpos = pos; if (!noSnap) { snappedpos = AL::sigmap.raster(pos, *_raster); } @@ -525,12 +539,16 @@ void PartCanvas::resizeItem(CItem* i, bool noSnap, bool ctrl) // first create local Item //--------------------------------------------------------- -CItem* PartCanvas::newItem(const QPoint& pos, int) +CItem* PartCanvas::newItem(const QPoint& pos, int key_modifiers) { int x = pos.x(); if (x < 0) x = 0; - x = AL::sigmap.raster(x, *_raster); + if(!(key_modifiers & Qt::ShiftModifier)) + x = AL::sigmap.raster1(x, *_raster); + int len = pos.x() - x; + if(len < 0) + len = 0; unsigned trackIndex = y2pitch(pos.y()); if (trackIndex >= tracks->size()) return 0; @@ -546,12 +564,12 @@ CItem* PartCanvas::newItem(const QPoint& pos, int) case MusECore::Track::NEW_DRUM: pa = new MusECore::MidiPart((MusECore::MidiTrack*)track); pa->setTick(x); - pa->setLenTick(0); + pa->setLenTick(len); break; case MusECore::Track::WAVE: pa = new MusECore::WavePart((MusECore::WaveTrack*)track); pa->setTick(x); - pa->setLenTick(0); + pa->setLenTick(len); break; case MusECore::Track::AUDIO_OUTPUT: case MusECore::Track::AUDIO_INPUT: @@ -572,8 +590,68 @@ CItem* PartCanvas::newItem(const QPoint& pos, int) void PartCanvas::newItem(CItem* i, bool noSnap) { - MusECore::Part* p = ((NPart*)(i))->part(); + if(!i) + return; + NPart* npart = (NPart*)(i); + MusECore::Part* p = npart->part(); + if(!p) + return; + MusECore::Track* part_track = p->track(); + if(!part_track) + return; + + int x = i->x(); + if (x < 0) + x = 0; + if(!noSnap) + x = AL::sigmap.raster1(x, *_raster); + p->setTick(x); + + unsigned trackIndex = y2pitch(i->y()); + unsigned int tsize = tracks->size(); + if (trackIndex >= tsize) + trackIndex = (tsize > 0 ? tsize - 1 : 0); + MusECore::Track* track = tracks->index(trackIndex); + if(track != part_track) + { + if(track->type() == part_track->type()) + { + p->setTrack(track); + p->setName(track->name()); + } + else + { + MusECore::Part* new_part = 0; + switch(track->type()) + { + case MusECore::Track::MIDI: + case MusECore::Track::DRUM: + case MusECore::Track::NEW_DRUM: + new_part = new MusECore::MidiPart((MusECore::MidiTrack*)track); + break; + case MusECore::Track::WAVE: + new_part = new MusECore::WavePart((MusECore::WaveTrack*)track); + break; + case MusECore::Track::AUDIO_OUTPUT: + case MusECore::Track::AUDIO_INPUT: + case MusECore::Track::AUDIO_GROUP: + case MusECore::Track::AUDIO_AUX: + case MusECore::Track::AUDIO_SOFTSYNTH: + break; + } + if(new_part) + { + new_part->setTick(p->tick()); + new_part->setName(track->name()); + new_part->setColorIndex(curColorIndex); + delete p; + npart->setPart(new_part); + p = new_part; + } + } + } + int len = i->width(); if (!noSnap) len = AL::sigmap.raster(len, *_raster); @@ -633,6 +711,8 @@ QMenu* PartCanvas::genItemPopup(CItem* item) QMenu* partPopup = new QMenu(this); + partPopup->addAction(new MenuTitleItem(tr("Part:"), partPopup)); + QAction *act_cut = partPopup->addAction(*editcutIconSet, tr("C&ut")); act_cut->setData(4); act_cut->setShortcut(Qt::CTRL+Qt::Key_X); @@ -713,7 +793,8 @@ QMenu* PartCanvas::genItemPopup(CItem* item) act_delete->setEnabled( true); act_cut->setEnabled( true); act_declone->setEnabled( rc > 1); - + + genCanvasPopup(partPopup); return partPopup; } @@ -723,6 +804,12 @@ QMenu* PartCanvas::genItemPopup(CItem* item) void PartCanvas::itemPopup(CItem* item, int n, const QPoint& pt) { + if(n >= TOOLS_ID_BASE) + { + canvasPopup(n); + return; + } + MusECore::PartList* pl = new MusECore::PartList; NPart* npart = (NPart*)(item); pl->add(npart->part()); @@ -878,24 +965,26 @@ bool PartCanvas::mousePress(QMouseEvent* event) return true; } QPoint pt = event->pos(); + Qt::MouseButton button = event->button(); CItem* item = items.find(pt); switch (_tool) { default: - if (item) + break; + case PointerTool: + case PencilTool: + if (item && button == Qt::LeftButton) emit trackChanged(item->part()->track()); - //else -- don't see the point of removing track selection, commenting out (rj) - // emit trackChanged(NULL); break; case CutTool: - if (item) splitItem(item, pt); + if (item && button == Qt::LeftButton) splitItem(item, pt); break; case GlueTool: - if (item) glueItem(item); + if (item && button == Qt::LeftButton) glueItem(item); break; case MuteTool: { - if (item) { + if (item && button == Qt::LeftButton) { NPart* np = (NPart*) item; MusECore::Part* p = np->part(); p->setMute(!p->mute()); @@ -903,31 +992,40 @@ bool PartCanvas::mousePress(QMouseEvent* event) break; } } + break; case AutomationTool: - if (event->button() & Qt::RightButton || - event->button() & Qt::MidButton) { + if (button == Qt::RightButton || + button == Qt::MidButton) { - bool do_delete; + bool do_delete = false; - if (event->button() & Qt::MidButton) // mid-click + if (button == Qt::MidButton) // mid-click do_delete=true; else // right-click { QMenu *automationMenu = new QMenu(this); QAction* act; + automationMenu->addAction(new MenuTitleItem(tr("Automation:"), automationMenu)); act = automationMenu->addAction(tr("Remove selected")); + act->setData(0); + genCanvasPopup(automationMenu); act = automationMenu->exec(event->globalPos()); - if (act) - do_delete=true; - else - do_delete=false; + if(act) + { + int n = act->data().toInt(); + if(n == 0) + do_delete = true; + else + if(n >= TOOLS_ID_BASE) + canvasPopup(n); + } + delete automationMenu; } if (do_delete && automation.currentTrack) { foreach(int frame, automation.currentCtrlFrameList) MusEGlobal::audio->msgEraseACEvent((MusECore::AudioTrack*)automation.currentTrack, automation.currentCtrlList->id(), frame); } - } else { if (automation.controllerState != doNothing) @@ -978,7 +1076,7 @@ MusECore::Track* PartCanvas::y2Track(int y) const { MusECore::TrackList* l = MusEGlobal::song->tracks(); int ty = 0; - for (MusECore::iTrack it = l->begin(); it != l->end(); ++it) { + for (MusECore::ciTrack it = l->begin(); it != l->end(); ++it) { int h = (*it)->height(); if (y >= ty && y < ty + h) return *it; @@ -1092,7 +1190,8 @@ void PartCanvas::keyPress(QKeyEvent* event) else if (key == shortcuts[SHRT_TOOL_LINEDRAW].key) { emit setUsedTool(AutomationTool); return; - } else if (key == shortcuts[SHRT_TOOL_GLUE].key) { + } + else if (key == shortcuts[SHRT_TOOL_GLUE].key) { emit setUsedTool(GlueTool); return; } @@ -1100,6 +1199,14 @@ void PartCanvas::keyPress(QKeyEvent* event) emit setUsedTool(MuteTool); return; } + else if (key == shortcuts[SHRT_TOOL_PAN].key) { + emit setUsedTool(PanTool); + return; + } + else if (key == shortcuts[SHRT_TOOL_ZOOM].key) { + emit setUsedTool(ZoomTool); + return; + } else if (key == shortcuts[SHRT_SEL_TRACK_ABOVE].key) { emit selectTrackAbove(); return; @@ -2180,13 +2287,25 @@ void PartCanvas::drawMoving(QPainter& p, const CItem* item, const QRect&) p.setPen( Qt::black); MusECore::Part* part = ((NPart*)item)->part(); QColor c(part->mute() ? Qt::white : MusEGlobal::config.partColors[part->colorIndex()]); - //c.setAlpha(MusEGlobal::config.globalAlphaBlend); DELETETHIS - c.setAlpha(128); // Fix this regardless of global setting. Should be OK. + c.setAlpha(128); // Fix this regardless of config.globalAlphaBlend setting. Should be OK. p.setBrush(c); - p.drawRect(item->mp().x(), item->mp().y(), item->width(), item->height()); + MusECore::TrackList* tl = MusEGlobal::song->tracks(); + int yy = 0; + int y = item->mp().y(); + int ih = item->height(); + for(MusECore::ciTrack it = tl->begin(); it != tl->end(); ++it) + { + int h = (*it)->height(); + if(y < yy+h) + { + ih = h; + break; + } + yy += h; + } + p.drawRect(item->mp().x(), item->mp().y(), item->width(), ih); } - //--------------------------------------------------------- // drawMidiPart // bb - bounding box of paint area @@ -2834,7 +2953,7 @@ void PartCanvas::paste(bool clone, paste_mode_t paste_mode, bool to_single_track if (to_single_track) { MusECore::TrackList* tl = MusEGlobal::song->tracks(); - for (MusECore::iTrack i = tl->begin(); i != tl->end(); ++i) { + for (MusECore::ciTrack i = tl->begin(); i != tl->end(); ++i) { if ((*i)->selected()) { if (track) { QMessageBox::critical(this, QString("MusE"), @@ -3227,7 +3346,7 @@ void PartCanvas::drawCanvas(QPainter& p, const QRect& rect) MusECore::TrackList* tl = MusEGlobal::song->tracks(); int yy = -rmapy(yorg) - ypos; int th; - for (MusECore::iTrack it = tl->begin(); it != tl->end(); ++it) { + for (MusECore::ciTrack it = tl->begin(); it != tl->end(); ++it) { if (yy > my + mh) break; MusECore::Track* track = *it; @@ -3282,7 +3401,7 @@ void PartCanvas::drawTopItem(QPainter& p, const QRect& rect) int yoff = -rmapy(yorg) - ypos; int yy = yoff; int th; - for (MusECore::iTrack it = tl->begin(); it != tl->end(); ++it) { + for (MusECore::ciTrack it = tl->begin(); it != tl->end(); ++it) { if (yy > my + mh) break; MusECore::Track* track = *it; @@ -3318,7 +3437,7 @@ void PartCanvas::drawTopItem(QPainter& p, const QRect& rect) // should be enhanced with solution that draws waveform also int yPos = yoff; if (MusEGlobal::song->record() && MusEGlobal::audio->isPlaying()) { - for (MusECore::iTrack it = tl->begin(); it != tl->end(); ++it) { + for (MusECore::ciTrack it = tl->begin(); it != tl->end(); ++it) { MusECore::Track* track = *it; th = track->height(); if (!th) @@ -3344,7 +3463,7 @@ void PartCanvas::drawTopItem(QPainter& p, const QRect& rect) // draw midi events on yPos=0; if (MusEGlobal::song->record() && MusEGlobal::audio->isPlaying()) { - for (MusECore::iTrack it = tl->begin(); it != tl->end(); ++it) { + for (MusECore::ciTrack it = tl->begin(); it != tl->end(); ++it) { MusECore::Track* track = *it; if (track->isMidiTrack() && track->recordFlag()) { @@ -3354,7 +3473,7 @@ void PartCanvas::drawTopItem(QPainter& p, const QRect& rect) MusECore::MPEventList *el = mt->mpevents(); if (el->size()) { - for (MusECore::iMPEvent i = el->begin(); i != el->end(); ++i) { + for (MusECore::ciMPEvent i = el->begin(); i != el->end(); ++i) { MusECore::MidiPlayEvent pe = *i; if (pe.isNote() && !pe.isNoteOff()) { @@ -3884,7 +4003,7 @@ double PartCanvas::valToLog(double inV, double min, double max) // 2 move only vertical //--------------------------------------------------------- -void PartCanvas::endMoveItems(const QPoint& pos, DragType dragtype, int dir) +void PartCanvas::endMoveItems(const QPoint& pos, DragType dragtype, int dir, bool rasterize) { int dp = y2pitch(pos.y()) - y2pitch(start.y()); int dx = pos.x() - start.x(); @@ -3894,7 +4013,7 @@ void PartCanvas::endMoveItems(const QPoint& pos, DragType dragtype, int dir) else if (dir == 2) dx = 0; - moveCanvasItems(moving, dp, dx, dragtype); + moveCanvasItems(moving, dp, dx, dragtype, rasterize); moving.clear(); updateSelection(); diff --git a/muse2/muse/arranger/pcanvas.h b/muse2/muse/arranger/pcanvas.h index 00ae2373..d34a26b6 100644 --- a/muse2/muse/arranger/pcanvas.h +++ b/muse2/muse/arranger/pcanvas.h @@ -116,12 +116,14 @@ class PartCanvas : public Canvas { virtual QPoint raster(const QPoint&) const; virtual int y2pitch(int y) const; virtual int pitch2y(int p) const; + virtual int y2height(int) const; + virtual inline int yItemOffset() const { return 0; } virtual CItem* newItem(const QPoint&, int); virtual void resizeItem(CItem*,bool, bool ctrl); virtual void newItem(CItem*,bool); virtual bool deleteItem(CItem*); - virtual void moveCanvasItems(CItemList&, int, int, DragType); + virtual void moveCanvasItems(CItemList&, int, int, DragType, bool rasterize = true); virtual bool moveItem(MusECore::Undo& operations, CItem*, const QPoint&, DragType); virtual void updateSong(DragType, MusECore::SongChangedFlags_t); @@ -154,7 +156,7 @@ class PartCanvas : public Canvas { protected: virtual void drawCanvas(QPainter&, const QRect&); - virtual void endMoveItems(const QPoint&, DragType, int dir); + virtual void endMoveItems(const QPoint&, DragType, int dir, bool rasterize = true); signals: void timeChanged(unsigned); diff --git a/muse2/muse/conf.cpp b/muse2/muse/conf.cpp index 417345c0..1f20d79b 100644 --- a/muse2/muse/conf.cpp +++ b/muse2/muse/conf.cpp @@ -965,6 +965,8 @@ void readConfiguration(Xml& xml, bool doReadMidiPortConfig, bool doReadGlobalCon MusEGlobal::config.unhideTracks = xml.parseInt(); else if (tag == "smartFocus") MusEGlobal::config.smartFocus = xml.parseInt(); + else if (tag == "borderlessMouse") + MusEGlobal::config.borderlessMouse = xml.parseInt(); else if (tag == "velocityPerNote") MusEGlobal::config.velocityPerNote = xml.parseInt(); else if (tag == "plugin_groups") @@ -1314,6 +1316,7 @@ void MusE::writeGlobalConfiguration(int level, MusECore::Xml& xml) const xml.intTag(level, "leftMouseButtonCanDecrease", MusEGlobal::config.leftMouseButtonCanDecrease); xml.intTag(level, "rangeMarkerWithoutMMB", MusEGlobal::config.rangeMarkerWithoutMMB); xml.intTag(level, "smartFocus", MusEGlobal::config.smartFocus); + xml.intTag(level, "borderlessMouse", MusEGlobal::config.borderlessMouse); xml.intTag(level, "velocityPerNote", MusEGlobal::config.velocityPerNote); xml.intTag(level, "unhideTracks", MusEGlobal::config.unhideTracks); diff --git a/muse2/muse/ctrl/ctrlcanvas.cpp b/muse2/muse/ctrl/ctrlcanvas.cpp index 9c19cf8b..1825d75d 100644 --- a/muse2/muse/ctrl/ctrlcanvas.cpp +++ b/muse2/muse/ctrl/ctrlcanvas.cpp @@ -191,12 +191,16 @@ CtrlCanvas::CtrlCanvas(MidiEditor* e, QWidget* parent, int xmag, setBg(Qt::white); setFont(MusEGlobal::config.fonts[3]); editor = e; + _panel = pnl; drag = DRAG_OFF; tool = MusEGui::PointerTool; pos[0] = 0; pos[1] = 0; pos[2] = 0; noEvents=false; + _perNoteVeloMode = MusEGlobal::config.velocityPerNote; + if(_panel) + _panel->setVeloPerNoteMode(_perNoteVeloMode); if (dynamic_cast<DrumEdit*>(editor) && dynamic_cast<DrumEdit*>(editor)->old_style_drummap_mode()==false) filterTrack=true; @@ -205,7 +209,6 @@ CtrlCanvas::CtrlCanvas(MidiEditor* e, QWidget* parent, int xmag, ctrl = &veloList; _controller = &MusECore::veloCtrl; - _panel = pnl; _cnum = MusECore::CTRL_VELOCITY; _dnum = MusECore::CTRL_VELOCITY; _didx = MusECore::CTRL_VELOCITY; @@ -233,6 +236,17 @@ CtrlCanvas::~CtrlCanvas() } //--------------------------------------------------------- +// setPanel +//--------------------------------------------------------- + +void CtrlCanvas::setPanel(CtrlPanel* pnl) +{ + _panel = pnl; + if(_panel) + _panel->setVeloPerNoteMode(_perNoteVeloMode); +} + +//--------------------------------------------------------- // setPos // set one of three markers // idx - 0-cpos 1-lpos 2-rpos @@ -602,14 +616,14 @@ void CtrlCanvas::updateItems() for (MusECore::iEvent i = el->begin(); i != el->end(); ++i) { MusECore::Event e = i->second; - // Added by T356. Do not add events which are past the end of the part. + // Do not add events which are past the end of the part. if(e.tick() >= len) break; if(_cnum == MusECore::CTRL_VELOCITY && e.type() == MusECore::Note) { newev = 0; - if (curDrumPitch == -1 || !MusEGlobal::config.velocityPerNote) // and NOT >=0 + if (curDrumPitch == -1 || !_perNoteVeloMode) // and NOT >=0 items.add(newev = new CEvent(e, part, e.velo())); else if (e.dataA() == curDrumPitch) //same note. if curDrumPitch==-2, this never is true items.add(newev = new CEvent(e, part, e.velo())); @@ -892,6 +906,15 @@ void CtrlCanvas::viewMouseReleaseEvent(QMouseEvent* event) } //--------------------------------------------------------- +// wheelEvent +//--------------------------------------------------------- + +void CtrlCanvas::wheelEvent(QWheelEvent* ev) +{ + emit redirectWheelEvent(ev); +} + +//--------------------------------------------------------- // newValRamp //--------------------------------------------------------- @@ -2076,4 +2099,13 @@ void CtrlCanvas::curPartHasChanged(MusECore::Part*) songChanged(SC_EVENT_MODIFIED); } +void CtrlCanvas::setPerNoteVeloMode(bool v) +{ + if(v == _perNoteVeloMode) + return; + _perNoteVeloMode = v; + if(_cnum == MusECore::CTRL_VELOCITY) + updateItems(); +} + } // namespace MusEGui diff --git a/muse2/muse/ctrl/ctrlcanvas.h b/muse2/muse/ctrl/ctrlcanvas.h index d1ee2e04..df52cfd7 100644 --- a/muse2/muse/ctrl/ctrlcanvas.h +++ b/muse2/muse/ctrl/ctrlcanvas.h @@ -32,6 +32,7 @@ #include "midictrl.h" #include "event.h" +class QWheelEvent; class QMouseEvent; class QEvent; class QWidget; @@ -118,6 +119,7 @@ class CtrlCanvas : public MusEGui::View { void viewMousePressEvent(QMouseEvent* event); void viewMouseMoveEvent(QMouseEvent*); void viewMouseReleaseEvent(QMouseEvent*); + virtual void wheelEvent(QWheelEvent*); virtual void draw(QPainter&, const QRect&); virtual void pdraw(QPainter&, const QRect&); @@ -155,6 +157,7 @@ class CtrlCanvas : public MusEGui::View { MusEGui::Tool tool; unsigned pos[3]; int curDrumPitch; //Used by the drum-editor to view velocity of only one key (one drum) + bool _perNoteVeloMode; void leaveEvent(QEvent*e); QPoint raster(const QPoint&) const; @@ -184,16 +187,19 @@ class CtrlCanvas : public MusEGui::View { void followEvent(int); void xposChanged(unsigned); void yposChanged(int); + void redirectWheelEvent(QWheelEvent*); public: CtrlCanvas(MidiEditor*, QWidget* parent, int, const char* name = 0, CtrlPanel* pnl = 0); ~CtrlCanvas(); - void setPanel(CtrlPanel* pnl) { _panel = pnl; } + void setPanel(CtrlPanel* pnl); MusECore::MidiCtrlValList* ctrlValList() { return ctrl; } MusECore::MidiController* controller() { return _controller; } MusECore::MidiTrack* track() const { return curTrack; } int getCurDrumPitch() const { return curDrumPitch; } + bool perNoteVeloMode() const { return _perNoteVeloMode; } + void setPerNoteVeloMode(bool); }; } // namespace MusEGui diff --git a/muse2/muse/ctrl/ctrledit.cpp b/muse2/muse/ctrl/ctrledit.cpp index ec814f3e..6605fbc7 100644 --- a/muse2/muse/ctrl/ctrledit.cpp +++ b/muse2/muse/ctrl/ctrledit.cpp @@ -55,11 +55,11 @@ CtrlEdit::CtrlEdit(QWidget* parent, MidiEditor* e, int xmag, setObjectName(name); setAttribute(Qt::WA_DeleteOnClose); QHBoxLayout* hbox = new QHBoxLayout; - canvas = new CtrlCanvas(e, 0, xmag, "ctrlcanvas"); - panel = new CtrlPanel(0, e, canvas, "panel"); + canvas = new CtrlCanvas(e, this, xmag, "ctrlcanvas"); + panel = new CtrlPanel(this, e, canvas, "panel"); canvas->setPanel(panel); - QWidget* vscale = new MusEGui::VScale; + QWidget* vscale = new MusEGui::VScale(this); hbox->setContentsMargins(0, 0, 0, 0); hbox->setSpacing (0); @@ -78,6 +78,7 @@ CtrlEdit::CtrlEdit(QWidget* parent, MidiEditor* e, int xmag, connect(panel, SIGNAL(controllerChanged(int)), canvas, SLOT(setController(int))); connect(canvas, SIGNAL(xposChanged(unsigned)), SIGNAL(timeChanged(unsigned))); connect(canvas, SIGNAL(yposChanged(int)), SIGNAL(yposChanged(int))); + connect(canvas, SIGNAL(redirectWheelEvent(QWheelEvent*)), SIGNAL(redirectWheelEvent(QWheelEvent*))); } //--------------------------------------------------------- @@ -89,6 +90,7 @@ void CtrlEdit::writeStatus(int level, MusECore::Xml& xml) if (canvas->controller()) { xml.tag(level++, "ctrledit"); xml.intTag(level, "ctrlnum", canvas->controller()->num()); + xml.intTag(level, "perNoteVeloMode", canvas->perNoteVeloMode()); xml.tag(level, "/ctrledit"); } } @@ -113,6 +115,11 @@ void CtrlEdit::readStatus(MusECore::Xml& xml) int num = xml.parseInt(); canvas->setController(num); } + else if (tag == "perNoteVeloMode") { + bool v = xml.parseInt(); + canvas->setPerNoteVeloMode(v); + panel->setVeloPerNoteMode(v); + } else xml.unknown("CtrlEdit"); break; diff --git a/muse2/muse/ctrl/ctrledit.h b/muse2/muse/ctrl/ctrledit.h index 0e3a280b..0000523e 100644 --- a/muse2/muse/ctrl/ctrledit.h +++ b/muse2/muse/ctrl/ctrledit.h @@ -67,6 +67,7 @@ class CtrlEdit : public QWidget { void destroyedCtrl(CtrlEdit*); void enterCanvas(); void yposChanged(int); + void redirectWheelEvent(QWheelEvent*); public: CtrlEdit(QWidget*, MidiEditor* e, int xmag, diff --git a/muse2/muse/ctrl/ctrlpanel.cpp b/muse2/muse/ctrl/ctrlpanel.cpp index 7856f51c..c8ed9bbd 100644 --- a/muse2/muse/ctrl/ctrlpanel.cpp +++ b/muse2/muse/ctrl/ctrlpanel.cpp @@ -267,12 +267,6 @@ void CtrlPanel::songChanged(MusECore::SongChangedFlags_t type) // Is it simply a midi controller value adjustment? Forget it. if(type == SC_MIDI_CONTROLLER) return; - - if(type & SC_CONFIG) - { - if(_veloPerNoteButton->isChecked() != MusEGlobal::config.velocityPerNote) - _veloPerNoteButton->setChecked(MusEGlobal::config.velocityPerNote); - } } //--------------------------------------------------------- @@ -693,11 +687,18 @@ void CtrlPanel::ctrlRightClicked(const QPoint& p, int /*id*/) void CtrlPanel::velPerNoteClicked() { - if(MusEGlobal::config.velocityPerNote != _veloPerNoteButton->isChecked()) - { - MusEGlobal::config.velocityPerNote = _veloPerNoteButton->isChecked(); - MusEGlobal::muse->changeConfig(false); // Save settings? No, wait till close. - } + if(ctrlcanvas && _veloPerNoteButton->isChecked() != ctrlcanvas->perNoteVeloMode()) + ctrlcanvas->setPerNoteVeloMode(_veloPerNoteButton->isChecked()); +} + +//--------------------------------------------------------- +// setVeloPerNoteMode +//--------------------------------------------------------- + +void CtrlPanel::setVeloPerNoteMode(bool v) +{ + if(v != _veloPerNoteButton->isChecked()) + _veloPerNoteButton->setDown(v); } } // namespace MusEGui diff --git a/muse2/muse/ctrl/ctrlpanel.h b/muse2/muse/ctrl/ctrlpanel.h index a8c24c65..c887f71c 100644 --- a/muse2/muse/ctrl/ctrlpanel.h +++ b/muse2/muse/ctrl/ctrlpanel.h @@ -83,6 +83,7 @@ class CtrlPanel: public QWidget { public slots: void setHeight(int); void ctrlPopup(); + void setVeloPerNoteMode(bool); public: CtrlPanel(QWidget*, MidiEditor*, CtrlCanvas*, const char* name = 0); diff --git a/muse2/muse/driver/alsamidi.cpp b/muse2/muse/driver/alsamidi.cpp index f140224c..8e8e6702 100644 --- a/muse2/muse/driver/alsamidi.cpp +++ b/muse2/muse/driver/alsamidi.cpp @@ -292,7 +292,7 @@ void MidiAlsaDevice::writeRouting(int level, Xml& xml) const bool MidiAlsaDevice::putMidiEvent(const MidiPlayEvent& e) { if (MusEGlobal::midiOutputTrace) { - printf("MidiOut: Alsa: <%s>: ", name().toLatin1().constData()); + fprintf(stderr, "MidiOut: Alsa: <%s>: ", name().toLatin1().constData()); e.dump(); } int chn = e.channel(); diff --git a/muse2/muse/driver/jackmidi.cpp b/muse2/muse/driver/jackmidi.cpp index dbb052e6..134b2fab 100644 --- a/muse2/muse/driver/jackmidi.cpp +++ b/muse2/muse/driver/jackmidi.cpp @@ -336,7 +336,7 @@ void MidiJackDevice::recordEvent(MidiRecordEvent& event) event.setLoopNum(MusEGlobal::audio->loopCount()); if (MusEGlobal::midiInputTrace) { - printf("MidiIn Jack: <%s>: ", name().toLatin1().constData()); + fprintf(stderr, "MidiIn Jack: <%s>: ", name().toLatin1().constData()); event.dump(); } @@ -639,7 +639,7 @@ bool MidiJackDevice::queueEvent(const MidiPlayEvent& e) #endif if (MusEGlobal::midiOutputTrace) { - printf("MidiOut: Jack: <%s>: ", name().toLatin1().constData()); + fprintf(stderr, "MidiOut: Jack: <%s>: ", name().toLatin1().constData()); e.dump(); } diff --git a/muse2/muse/gconfig.cpp b/muse2/muse/gconfig.cpp index 0dc92c7a..79bad91d 100644 --- a/muse2/muse/gconfig.cpp +++ b/muse2/muse/gconfig.cpp @@ -210,7 +210,7 @@ GlobalConfigValues config = { MusEGlobal::PREFER_NEW, // drumTrackPreference true, // smartFocus 20, // trackHeight - + true // borderlessMouse }; } // namespace MusEGlobal diff --git a/muse2/muse/gconfig.h b/muse2/muse/gconfig.h index 52763032..44e982ab 100644 --- a/muse2/muse/gconfig.h +++ b/muse2/muse/gconfig.h @@ -215,7 +215,7 @@ struct GlobalConfigValues { drumTrackPreference_t drumTrackPreference; bool smartFocus; int trackHeight; - + bool borderlessMouse; }; diff --git a/muse2/muse/icons.cpp b/muse2/muse/icons.cpp index 2c48bcab..1a578c3e 100644 --- a/muse2/muse/icons.cpp +++ b/muse2/muse/icons.cpp @@ -63,6 +63,11 @@ #include "xpm/pencil.xpm" #include "xpm/delete.xpm" #include "xpm/play.xpm" +#include "xpm/closed_hand.xpm" +#include "xpm/open_hand.xpm" +#include "xpm/zoom.xpm" +#include "xpm/zoom_at.xpm" +#include "xpm/size_all.xpm" #include "xpm/record1.xpm" #include "xpm/record.xpm" @@ -325,6 +330,11 @@ QPixmap* punchout1Icon; QPixmap* loopIcon; QPixmap* loop1Icon; QPixmap* playIcon; +QPixmap* closedHandIcon; +QPixmap* openHandIcon; +QPixmap* zoomIcon; +QPixmap* zoomAtIcon; +QPixmap* sizeAllIcon; QPixmap* record1_Icon; QPixmap* record_on_Icon; @@ -538,6 +548,11 @@ void initIcons() loopIcon = new MPIXMAP(loop_xpm, NULL); loop1Icon = new MPIXMAP(loop1_xpm, NULL); playIcon = new MPIXMAP(play_xpm, "media-playback-start"); + closedHandIcon = new MPIXMAP(closed_hand_xpm, NULL); + openHandIcon = new MPIXMAP(open_hand_xpm, NULL); + zoomIcon = new MPIXMAP(zoom_xpm, NULL); + zoomAtIcon = new MPIXMAP(zoom_at_xpm, NULL); + sizeAllIcon = new MPIXMAP(size_all_xpm, NULL); record1_Icon = new MPIXMAP(record1_xpm, NULL); record_on_Icon = new MPIXMAP(record_on_xpm, NULL); @@ -794,6 +809,11 @@ void deleteIcons() delete loopIcon; delete loop1Icon; delete playIcon; + delete closedHandIcon; + delete openHandIcon; + delete zoomIcon; + delete zoomAtIcon; + delete sizeAllIcon; delete record1_Icon; delete record_on_Icon; diff --git a/muse2/muse/icons.h b/muse2/muse/icons.h index 2bba40cd..a2222489 100644 --- a/muse2/muse/icons.h +++ b/muse2/muse/icons.h @@ -67,7 +67,11 @@ extern QPixmap* steprecIcon; extern QPixmap* glueIcon; extern QPixmap* drawIcon; extern QPixmap* cursorIcon; - +extern QPixmap* closedHandIcon; +extern QPixmap* openHandIcon; +extern QPixmap* zoomIcon; +extern QPixmap* zoomAtIcon; +extern QPixmap* sizeAllIcon; extern QPixmap* quantIcon; extern QPixmap* printIcon; diff --git a/muse2/muse/mididev.cpp b/muse2/muse/mididev.cpp index 8657991f..7df443a0 100644 --- a/muse2/muse/mididev.cpp +++ b/muse2/muse/mididev.cpp @@ -236,7 +236,7 @@ void MidiDevice::recordEvent(MidiRecordEvent& event) event.setLoopNum(MusEGlobal::audio->loopCount()); if (MusEGlobal::midiInputTrace) { - printf("MidiInput: "); + fprintf(stderr, "MidiInput: "); event.dump(); } @@ -288,7 +288,7 @@ void MidiDevice::recordEvent(MidiRecordEvent& event) if (!applyMidiInputTransformation(event)) { if (MusEGlobal::midiInputTrace) - printf(" midi input transformation: event filtered\n"); + fprintf(stderr, " midi input transformation: event filtered\n"); return; } @@ -313,7 +313,7 @@ void MidiDevice::recordEvent(MidiRecordEvent& event) // Split the events up into channel fifos. Special 'channel' number 17 for sysex events. unsigned int ch = (typ == ME_SYSEX)? MIDI_CHANNELS : event.channel(); if(_recordFifo[ch].put(event)) - printf("MidiDevice::recordEvent: fifo channel %d overflow\n", ch); + fprintf(stderr, "MidiDevice::recordEvent: fifo channel %d overflow\n", ch); } //--------------------------------------------------------- @@ -530,7 +530,7 @@ bool MidiDevice::putEvent(const MidiPlayEvent& ev) sendNullRPNParams(t, port, chn, true); } else { - printf("putEvent: unknown controller type 0x%x\n", a); + fprintf(stderr, "putEvent: unknown controller type 0x%x\n", a); } return false; #endif 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&); diff --git a/muse2/muse/midieditor.cpp b/muse2/muse/midieditor.cpp index 50cc6003..13e6edc5 100644 --- a/muse2/muse/midieditor.cpp +++ b/muse2/muse/midieditor.cpp @@ -245,24 +245,6 @@ void MidiEditor::setCurCanvasPart(MusECore::Part* part) canvas->setCurrentPart(part); } -void MidiEditor::horizontalZoom(bool zoom_in, int pos_offset) -{ - 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); - hscroll->setMag(newmag, pos_offset); -} - void MidiEditor::addNewParts(const std::map< MusECore::Part*, std::set<MusECore::Part*> >& param) { using std::map; diff --git a/muse2/muse/midieditor.h b/muse2/muse/midieditor.h index 0131fafb..900f06b1 100644 --- a/muse2/muse/midieditor.h +++ b/muse2/muse/midieditor.h @@ -32,7 +32,7 @@ class QGridLayout; class QWidget; - +class QPoint; namespace MusECore { class Part; @@ -81,7 +81,6 @@ class MidiEditor : public TopWin { public slots: void songChanged(MusECore::SongChangedFlags_t type); void setCurDrumInstrument(int instr); - void horizontalZoom(bool zoom_in, int pos_offset); virtual void updateHScrollRange() { }; signals: diff --git a/muse2/muse/mpevent.cpp b/muse2/muse/mpevent.cpp index a760be8b..94f38007 100644 --- a/muse2/muse/mpevent.cpp +++ b/muse2/muse/mpevent.cpp @@ -21,6 +21,8 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //========================================================= +#include <stdio.h> + #include "mpevent.h" #include "helper.h" @@ -67,7 +69,7 @@ MEvent::MEvent(unsigned tick, int port, int channel, const Event& e) setData(e.eventData()); break; default: - printf("MEvent::MEvent(): event type %d not implemented\n", + fprintf(stderr, "MEvent::MEvent(): event type %d not implemented\n", type()); break; } @@ -79,16 +81,20 @@ MEvent::MEvent(unsigned tick, int port, int channel, const Event& e) void MEvent::dump() const { - printf("time:%d port:%d chan:%d ", _time, _port, _channel+1); - if (_type == 0x90) { // NoteOn + fprintf(stderr, "time:%d port:%d chan:%d ", _time, _port, _channel+1); + if (_type == ME_NOTEON) { + QString s = pitch2string(_a); + fprintf(stderr, "NoteOn %s(0x%x) %d\n", s.toLatin1().constData(), _a, _b); + } + else if (_type == ME_NOTEOFF) { QString s = pitch2string(_a); - printf("NoteOn %s(0x%x) %d\n", s.toLatin1().constData(), _a, _b); + fprintf(stderr, "NoteOff %s(0x%x) %d\n", s.toLatin1().constData(), _a, _b); } - else if (_type == 0xf0) { - printf("SysEx len %d 0x%0x ...\n", len(), data()[0]); + else if (_type == ME_SYSEX) { + fprintf(stderr, "SysEx len %d 0x%0x ...\n", len(), data()[0]); } else - printf("type:0x%02x a=%d b=%d\n", _type, _a, _b); + fprintf(stderr, "type:0x%02x a=%d b=%d\n", _type, _a, _b); } //--------------------------------------------------------- @@ -184,7 +190,7 @@ int MEvent::sortingWeight() const return 27; } - printf("FIXME: MEvent::sortingWeight: unknown event type:%d\n", _type); + fprintf(stderr, "FIXME: MEvent::sortingWeight: unknown event type:%d\n", _type); return 100; } diff --git a/muse2/muse/shortcuts.cpp b/muse2/muse/shortcuts.cpp index 2be06e9b..fdf021ff 100644 --- a/muse2/muse/shortcuts.cpp +++ b/muse2/muse/shortcuts.cpp @@ -64,7 +64,7 @@ void initShortCuts() defShrt(SHRT_CONFIG_SHORTCUTS, Qt::CTRL + Qt::SHIFT + Qt::Key_F1, QT_TRANSLATE_NOOP("shortcuts", "Settings: Configure shortcuts"), GLOBAL_SHRT, "configure_key_shortcuts"); defShrt(SHRT_COPY, Qt::CTRL + Qt::Key_C, QT_TRANSLATE_NOOP("shortcuts", "Edit: Copy"), INVIS_SHRT, "copy"); - defShrt(SHRT_COPY_RANGE, Qt::CTRL + Qt::SHIFT + Qt::Key_C, QT_TRANSLATE_NOOP("shortcuts", "Edit: Copy in range"), GLOBAL_SHRT, "copy_range"); + defShrt(SHRT_COPY_RANGE, Qt::CTRL + Qt::SHIFT + Qt::Key_C, QT_TRANSLATE_NOOP("shortcuts", "Edit: Copy in range"), SCORE_SHRT + PROLL_SHRT + DEDIT_SHRT + ARRANG_SHRT, "copy_range"); defShrt(SHRT_UNDO, Qt::CTRL + Qt::Key_Z, QT_TRANSLATE_NOOP("shortcuts", "Edit: Undo"), INVIS_SHRT, "undo"); defShrt(SHRT_REDO, Qt::CTRL + Qt::SHIFT + Qt::Key_Z, QT_TRANSLATE_NOOP("shortcuts", "Edit: Redo"), INVIS_SHRT, "redo"); defShrt(SHRT_CUT, Qt::CTRL + Qt::Key_X, QT_TRANSLATE_NOOP("shortcuts", "Edit: Cut"), INVIS_SHRT, "cut"); @@ -72,7 +72,7 @@ void initShortCuts() defShrt(SHRT_PASTE_TO_TRACK, Qt::CTRL + Qt::SHIFT + Qt::Key_V, QT_TRANSLATE_NOOP("shortcuts", "Edit: Paste to selected track"), ARRANG_SHRT, "paste_to_track"); defShrt(SHRT_PASTE_CLONE, Qt::CTRL + Qt::Key_B, QT_TRANSLATE_NOOP("shortcuts", "Edit: Paste clone"), ARRANG_SHRT, "paste_clones"); defShrt(SHRT_PASTE_CLONE_TO_TRACK, Qt::CTRL + Qt::SHIFT + Qt::Key_B, QT_TRANSLATE_NOOP("shortcuts", "Edit: Paste clone to selected track"), ARRANG_SHRT, "paste_clones_to_track"); - defShrt(SHRT_PASTE_DIALOG, Qt::CTRL + Qt::Key_G, QT_TRANSLATE_NOOP("shortcuts", "Edit: Paste (with dialog)"), GLOBAL_SHRT, "paste_with_dialog"); + defShrt(SHRT_PASTE_DIALOG, Qt::CTRL + Qt::Key_G, QT_TRANSLATE_NOOP("shortcuts", "Edit: Paste (with dialog)"), SCORE_SHRT + PROLL_SHRT + DEDIT_SHRT + ARRANG_SHRT, "paste_with_dialog"); defShrt(SHRT_DELETE, Qt::Key_Delete, QT_TRANSLATE_NOOP("shortcuts", "Edit: Delete"), INVIS_SHRT, "delete"); //----------------------------------------------------------- @@ -96,7 +96,7 @@ void initShortCuts() defShrt(SHRT_OPEN_PIANO, Qt::CTRL + Qt::Key_E, QT_TRANSLATE_NOOP("shortcuts", "Open pianoroll"), ARRANG_SHRT, "open_pianoroll"); defShrt(SHRT_OPEN_DRUMS, Qt::CTRL + Qt::Key_D, QT_TRANSLATE_NOOP("shortcuts", "Open drumeditor"), ARRANG_SHRT, "open_drumedit"); defShrt(SHRT_OPEN_LIST, Qt::CTRL + Qt::Key_L, QT_TRANSLATE_NOOP("shortcuts", "Open listeditor"), ARRANG_SHRT, "open_listedit"); - defShrt(SHRT_OPEN_WAVE, Qt::CTRL + Qt::Key_W, QT_TRANSLATE_NOOP("shortcuts", "Open waveeditor"), ARRANG_SHRT, "open_waveedit"); + defShrt(SHRT_OPEN_WAVE, Qt::CTRL + Qt::Key_Y, QT_TRANSLATE_NOOP("shortcuts", "Open waveeditor"), ARRANG_SHRT, "open_waveeditor"); defShrt(SHRT_OPEN_GRAPHIC_MASTER, Qt::CTRL + Qt::Key_M, QT_TRANSLATE_NOOP("shortcuts", "Open graphical mastertrack editor"), ARRANG_SHRT, "open_graph_master"); defShrt(SHRT_OPEN_LIST_MASTER, Qt::CTRL + Qt::SHIFT + Qt::Key_M, QT_TRANSLATE_NOOP("shortcuts", "Open list mastertrack editor"), ARRANG_SHRT, "open_list_master"); defShrt(SHRT_OPEN_MIDI_TRANSFORM, Qt::CTRL + Qt::Key_T, QT_TRANSLATE_NOOP("shortcuts", "Open midi transformer"), ARRANG_SHRT, "open_midi_transform"); @@ -155,7 +155,7 @@ void initShortCuts() // defShrt(SHRT_OPEN_CLIPS, 0, QT_TRANSLATE_NOOP("shortcuts", "View audio clips"), ARRANG_SHRT, "view_audio_clips"); defShrt(SHRT_OPEN_HELP, Qt::Key_F1, QT_TRANSLATE_NOOP("shortcuts", "Help: Open Manual"), ARRANG_SHRT, "open_help"); - defShrt(SHRT_START_WHATSTHIS, Qt::SHIFT + Qt::Key_F1, QT_TRANSLATE_NOOP("shortcuts", "Help: Toggle whatsthis mode"), ARRANG_SHRT, "toggle_whatsthis"); + defShrt(SHRT_START_WHATSTHIS, Qt::SHIFT + Qt::Key_F1, QT_TRANSLATE_NOOP("shortcuts", "Help: Toggle whatsthis mode"), ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT, "toggle_whatsthis"); defShrt(SHRT_EDIT_PART, Qt::Key_Return, QT_TRANSLATE_NOOP("shortcuts", "Edit: Edit selected part"), ARRANG_SHRT, "edit_selected_part"); defShrt(SHRT_SEL_ABOVE, Qt::Key_Up, QT_TRANSLATE_NOOP("shortcuts", "Edit: Select nearest part on track above"), ARRANG_SHRT, "sel_part_above"); @@ -170,63 +170,65 @@ void initShortCuts() //----------------------------------------------------------- - defShrt(SHRT_TRANSPOSE, 0, QT_TRANSLATE_NOOP("shortcuts", "Midi: Transpose"), ARRANG_SHRT + PROLL_SHRT, "midi_transpose"); + defShrt(SHRT_TRANSPOSE, 0, QT_TRANSLATE_NOOP("shortcuts", "Midi: Transpose"), ARRANG_SHRT + PROLL_SHRT + SCORE_SHRT, "midi_transpose"); //----------------------------------------------------------- - defShrt(SHRT_SELECT_ALL, Qt::CTRL + Qt::Key_A, QT_TRANSLATE_NOOP("shortcuts", "Edit: Select all"), ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT, "sel_all"); - defShrt(SHRT_SELECT_NONE, Qt::CTRL + Qt::SHIFT + Qt::Key_A, QT_TRANSLATE_NOOP("shortcuts", "Edit: Select none"), ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT, "sel_none"); - defShrt(SHRT_SELECT_INVERT, Qt::CTRL + Qt::Key_I, QT_TRANSLATE_NOOP("shortcuts", "Edit: Invert Selection"), ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT, "sel_inv"); - defShrt(SHRT_SELECT_ILOOP, 0, QT_TRANSLATE_NOOP("shortcuts", "Edit: Select events/parts inside locators"), ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT, "sel_ins_loc"); - defShrt(SHRT_SELECT_OLOOP, 0, QT_TRANSLATE_NOOP("shortcuts", "Edit: Select events/parts outside locators"), ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT, "sel_out_loc"); - defShrt(SHRT_SELECT_PREV_PART, Qt::ALT + Qt::Key_Left, QT_TRANSLATE_NOOP("shortcuts", "Edit: Select previous part"), ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT, "sel_prv_prt"); - defShrt(SHRT_SELECT_NEXT_PART, Qt::ALT + Qt::Key_Right, QT_TRANSLATE_NOOP("shortcuts", "Edit: Select next part"), ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT, "sel_nxt_prt"); - defShrt(SHRT_SEL_LEFT, Qt::Key_Left, QT_TRANSLATE_NOOP("shortcuts", "Edit: Select nearest part/event to the left or move cursor"), ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT, "sel_left"); - defShrt(SHRT_SEL_LEFT_ADD, Qt::Key_Left + Qt::SHIFT, QT_TRANSLATE_NOOP("shortcuts", "Edit: Add nearest part/event to the left to selection"), PROLL_SHRT + DEDIT_SHRT, "sel_left_add"); - defShrt(SHRT_SEL_RIGHT, Qt::Key_Right, QT_TRANSLATE_NOOP("shortcuts", "Edit: Select nearest part/event to the right or move cursor"), ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT,"sel_right"); - defShrt(SHRT_SEL_RIGHT_ADD, Qt::Key_Right + Qt::SHIFT, QT_TRANSLATE_NOOP("shortcuts", "Edit: Add nearest part/event to the right to selection"), PROLL_SHRT + DEDIT_SHRT,"sel_right_add"); - defShrt(SHRT_LOCATORS_TO_SELECTION, Qt::ALT + Qt::Key_P, QT_TRANSLATE_NOOP("shortcuts", "Edit: Set locators to selection"), ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT, "loc_to_sel"); + defShrt(SHRT_SELECT_ALL, Qt::CTRL + Qt::Key_A, QT_TRANSLATE_NOOP("shortcuts", "Edit: Select all"), ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT + WAVE_SHRT + SCORE_SHRT, "sel_all"); + defShrt(SHRT_SELECT_NONE, Qt::CTRL + Qt::SHIFT + Qt::Key_A, QT_TRANSLATE_NOOP("shortcuts", "Edit: Select none"), ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT + WAVE_SHRT + SCORE_SHRT, "sel_none"); + defShrt(SHRT_SELECT_INVERT, Qt::CTRL + Qt::Key_I, QT_TRANSLATE_NOOP("shortcuts", "Edit: Invert Selection"), ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT + SCORE_SHRT, "sel_inv"); + defShrt(SHRT_SELECT_ILOOP, 0, QT_TRANSLATE_NOOP("shortcuts", "Edit: Select events/parts inside locators"), ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT + SCORE_SHRT, "sel_ins_loc"); + defShrt(SHRT_SELECT_OLOOP, 0, QT_TRANSLATE_NOOP("shortcuts", "Edit: Select events/parts outside locators"), ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT + SCORE_SHRT, "sel_out_loc"); + defShrt(SHRT_SELECT_PREV_PART, Qt::ALT + Qt::Key_Left, QT_TRANSLATE_NOOP("shortcuts", "Edit: Select previous part"), ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT + WAVE_SHRT, "sel_prv_prt"); + defShrt(SHRT_SELECT_NEXT_PART, Qt::ALT + Qt::Key_Right, QT_TRANSLATE_NOOP("shortcuts", "Edit: Select next part"), ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT + WAVE_SHRT, "sel_nxt_prt"); + defShrt(SHRT_SEL_LEFT, Qt::Key_Left, QT_TRANSLATE_NOOP("shortcuts", "Edit: Select nearest part/event to the left or move cursor"), ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT + WAVE_SHRT, "sel_left"); + defShrt(SHRT_SEL_LEFT_ADD, Qt::Key_Left + Qt::SHIFT, QT_TRANSLATE_NOOP("shortcuts", "Edit: Add nearest part/event to the left to selection"), PROLL_SHRT + DEDIT_SHRT + WAVE_SHRT, "sel_left_add"); + defShrt(SHRT_SEL_RIGHT, Qt::Key_Right, QT_TRANSLATE_NOOP("shortcuts", "Edit: Select nearest part/event to the right or move cursor"), ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT + WAVE_SHRT,"sel_right"); + defShrt(SHRT_SEL_RIGHT_ADD, Qt::Key_Right + Qt::SHIFT, QT_TRANSLATE_NOOP("shortcuts", "Edit: Add nearest part/event to the right to selection"), PROLL_SHRT + DEDIT_SHRT + WAVE_SHRT,"sel_right_add"); + defShrt(SHRT_LOCATORS_TO_SELECTION, Qt::ALT + Qt::Key_P, QT_TRANSLATE_NOOP("shortcuts", "Edit: Set locators to selection"), ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT + WAVE_SHRT, "loc_to_sel"); defShrt(SHRT_INC_PITCH, Qt::CTRL + Qt::Key_Up, QT_TRANSLATE_NOOP("shortcuts", "Edit: Increase pitch"), PROLL_SHRT + DEDIT_SHRT, "sel_inc_pitch"); defShrt(SHRT_DEC_PITCH, Qt::CTRL + Qt::Key_Down, QT_TRANSLATE_NOOP("shortcuts", "Edit: Decrease pitch"), PROLL_SHRT + DEDIT_SHRT, "sel_dec_pitch"); - defShrt(SHRT_INC_POS, Qt::CTRL + Qt::Key_Right, QT_TRANSLATE_NOOP("shortcuts", "Edit: Increase event position"), PROLL_SHRT + DEDIT_SHRT, "sel_inc_pos"); - defShrt(SHRT_DEC_POS, Qt::CTRL + Qt::Key_Left, QT_TRANSLATE_NOOP("shortcuts", "Edit: Decrease event position"), PROLL_SHRT + DEDIT_SHRT, "sel_dec_pos"); - defShrt(SHRT_ZOOM_IN, Qt::CTRL + Qt::Key_PageUp, QT_TRANSLATE_NOOP("shortcuts", "View: Zoom in"), PROLL_SHRT + DEDIT_SHRT + ARRANG_SHRT, "zoom_in"); - defShrt(SHRT_ZOOM_OUT, Qt::CTRL + Qt::Key_PageDown, QT_TRANSLATE_NOOP("shortcuts", "View: Zoom out"), PROLL_SHRT + DEDIT_SHRT + ARRANG_SHRT, "zoom_out"); - defShrt(SHRT_GOTO_CPOS, Qt::Key_C, QT_TRANSLATE_NOOP("shortcuts", "View: Goto Current Position"), PROLL_SHRT + DEDIT_SHRT, "goto_cpos"); - defShrt(SHRT_SCROLL_LEFT, Qt::Key_H, QT_TRANSLATE_NOOP("shortcuts", "View: Scroll left"), PROLL_SHRT + DEDIT_SHRT, "scroll_left"); - defShrt(SHRT_SCROLL_RIGHT, Qt::Key_L, QT_TRANSLATE_NOOP("shortcuts", "View: Scroll left"), PROLL_SHRT + DEDIT_SHRT, "scroll_right"); + defShrt(SHRT_INC_POS, Qt::CTRL + Qt::Key_Right, QT_TRANSLATE_NOOP("shortcuts", "Edit: Increase event position"), PROLL_SHRT + DEDIT_SHRT + WAVE_SHRT, "sel_inc_pos"); + defShrt(SHRT_DEC_POS, Qt::CTRL + Qt::Key_Left, QT_TRANSLATE_NOOP("shortcuts", "Edit: Decrease event position"), PROLL_SHRT + DEDIT_SHRT + WAVE_SHRT, "sel_dec_pos"); + defShrt(SHRT_ZOOM_IN, Qt::CTRL + Qt::Key_PageUp, QT_TRANSLATE_NOOP("shortcuts", "View: Zoom in"), PROLL_SHRT + DEDIT_SHRT + ARRANG_SHRT + WAVE_SHRT, "zoom_in"); + defShrt(SHRT_ZOOM_OUT, Qt::CTRL + Qt::Key_PageDown, QT_TRANSLATE_NOOP("shortcuts", "View: Zoom out"), PROLL_SHRT + DEDIT_SHRT + ARRANG_SHRT + WAVE_SHRT, "zoom_out"); + defShrt(SHRT_GOTO_CPOS, Qt::Key_C, QT_TRANSLATE_NOOP("shortcuts", "View: Goto Current Position"), PROLL_SHRT + DEDIT_SHRT + WAVE_SHRT, "goto_cpos"); + defShrt(SHRT_SCROLL_LEFT, Qt::Key_H, QT_TRANSLATE_NOOP("shortcuts", "View: Scroll left"), PROLL_SHRT + DEDIT_SHRT + WAVE_SHRT, "scroll_left"); + defShrt(SHRT_SCROLL_RIGHT, Qt::Key_L, QT_TRANSLATE_NOOP("shortcuts", "View: Scroll left"), PROLL_SHRT + DEDIT_SHRT + WAVE_SHRT, "scroll_right"); //----------------------------------------------------------- //Drum: //----------------------------------------------------------- - defShrt(SHRT_FIXED_LEN, Qt::ALT + Qt::Key_L, QT_TRANSLATE_NOOP("shortcuts", "Edit: Set Fixed Length on Midi Events"), PROLL_SHRT + DEDIT_SHRT, "midi_fixed_len"); + defShrt(SHRT_FIXED_LEN, Qt::ALT + Qt::Key_L, QT_TRANSLATE_NOOP("shortcuts", "Edit: Set Fixed Length on Midi Events"), PROLL_SHRT + DEDIT_SHRT + SCORE_SHRT, "midi_fixed_len"); //----------------------------------------------------------- //Pianoroll: //----------------------------------------------------------- - defShrt(SHRT_QUANTIZE, 0, QT_TRANSLATE_NOOP("shortcuts", "Quantize"), PROLL_SHRT, "midi_quant"); - defShrt(SHRT_MODIFY_GATE_TIME, 0, QT_TRANSLATE_NOOP("shortcuts", "Modify Note Length"), PROLL_SHRT, "midi_mod_gate_time"); - defShrt(SHRT_MODIFY_VELOCITY, 0, QT_TRANSLATE_NOOP("shortcuts", "Modify Velocity"), PROLL_SHRT, "midi_mod_velo"); - defShrt(SHRT_CRESCENDO, 0, QT_TRANSLATE_NOOP("shortcuts", "Edit: Crescendo"), PROLL_SHRT, "midi_crescendo"); - defShrt(SHRT_THIN_OUT, 0, QT_TRANSLATE_NOOP("shortcuts", "Edit: Thin Out"), PROLL_SHRT, "midi_thin_out"); - defShrt(SHRT_ERASE_EVENT, 0, QT_TRANSLATE_NOOP("shortcuts", "Edit: Erase Event"), PROLL_SHRT, "midi_erase_event"); - defShrt(SHRT_DELETE_OVERLAPS, 0, QT_TRANSLATE_NOOP("shortcuts", "Edit: Delete Overlaps"), PROLL_SHRT, "midi_delete_overlaps"); - defShrt(SHRT_NOTE_SHIFT, 0, QT_TRANSLATE_NOOP("shortcuts", "Edit: Note Shift"), PROLL_SHRT, "midi_note_shift"); - defShrt(SHRT_MOVE_CLOCK, 0, QT_TRANSLATE_NOOP("shortcuts", "Edit: Move Clock"), PROLL_SHRT, "midi_move_clock"); - defShrt(SHRT_COPY_MEASURE, 0, QT_TRANSLATE_NOOP("shortcuts", "Edit: Copy Measure"), PROLL_SHRT, "midi_copy_measure"); - defShrt(SHRT_ERASE_MEASURE, 0, QT_TRANSLATE_NOOP("shortcuts", "Edit: Erase Measure"), PROLL_SHRT,"midi_erase_measure"); - defShrt(SHRT_DELETE_MEASURE, 0, QT_TRANSLATE_NOOP("shortcuts", "Edit: Delete Measure"), PROLL_SHRT, "midi_delete_measure"); - defShrt(SHRT_CREATE_MEASURE, 0, QT_TRANSLATE_NOOP("shortcuts", "Edit: Create Measure"), PROLL_SHRT, "midi_create_measure"); - defShrt(SHRT_EVENT_COLOR, Qt::Key_E, QT_TRANSLATE_NOOP("shortcuts", "Edit: Change Event Color"), PROLL_SHRT, "change_event_color"); + defShrt(SHRT_QUANTIZE, 0, QT_TRANSLATE_NOOP("shortcuts", "Quantize"), PROLL_SHRT + DEDIT_SHRT + SCORE_SHRT, "midi_quant"); + defShrt(SHRT_MODIFY_GATE_TIME, 0, QT_TRANSLATE_NOOP("shortcuts", "Modify Note Length"), PROLL_SHRT + SCORE_SHRT, "midi_mod_gate_time"); + defShrt(SHRT_MODIFY_VELOCITY, 0, QT_TRANSLATE_NOOP("shortcuts", "Modify Velocity"), PROLL_SHRT + DEDIT_SHRT + SCORE_SHRT, "midi_mod_velo"); + defShrt(SHRT_CRESCENDO, 0, QT_TRANSLATE_NOOP("shortcuts", "Edit: Crescendo"), PROLL_SHRT + DEDIT_SHRT, "midi_crescendo"); + defShrt(SHRT_THIN_OUT, 0, QT_TRANSLATE_NOOP("shortcuts", "Edit: Thin Out"), PROLL_SHRT + DEDIT_SHRT, "midi_thin_out"); + defShrt(SHRT_ERASE_EVENT, 0, QT_TRANSLATE_NOOP("shortcuts", "Edit: Erase Event"), PROLL_SHRT + DEDIT_SHRT + SCORE_SHRT, "midi_erase_event"); + defShrt(SHRT_DELETE_OVERLAPS, 0, QT_TRANSLATE_NOOP("shortcuts", "Edit: Delete Overlaps"), PROLL_SHRT + DEDIT_SHRT + SCORE_SHRT, "midi_delete_overlaps"); + defShrt(SHRT_NOTE_SHIFT, 0, QT_TRANSLATE_NOOP("shortcuts", "Edit: Note Shift"), PROLL_SHRT + DEDIT_SHRT + SCORE_SHRT, "midi_note_shift"); + defShrt(SHRT_MOVE_CLOCK, 0, QT_TRANSLATE_NOOP("shortcuts", "Edit: Move Clock"), PROLL_SHRT + DEDIT_SHRT, "midi_move_clock"); + defShrt(SHRT_COPY_MEASURE, 0, QT_TRANSLATE_NOOP("shortcuts", "Edit: Copy Measure"), PROLL_SHRT + DEDIT_SHRT, "midi_copy_measure"); + defShrt(SHRT_ERASE_MEASURE, 0, QT_TRANSLATE_NOOP("shortcuts", "Edit: Erase Measure"), PROLL_SHRT + DEDIT_SHRT,"midi_erase_measure"); + defShrt(SHRT_DELETE_MEASURE, 0, QT_TRANSLATE_NOOP("shortcuts", "Edit: Delete Measure"), PROLL_SHRT + DEDIT_SHRT, "midi_delete_measure"); + defShrt(SHRT_CREATE_MEASURE, 0, QT_TRANSLATE_NOOP("shortcuts", "Edit: Create Measure"), PROLL_SHRT + DEDIT_SHRT, "midi_create_measure"); + defShrt(SHRT_EVENT_COLOR, Qt::Key_E, QT_TRANSLATE_NOOP("shortcuts", "Edit: Change Event Color"), PROLL_SHRT + SCORE_SHRT, "change_event_color"); // Shortcuts for tools // global - defShrt(SHRT_TOOL_POINTER, Qt::Key_A, QT_TRANSLATE_NOOP("shortcuts", "Tool: Pointer"), ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT, "pointer_tool"); - defShrt(SHRT_TOOL_PENCIL, Qt::Key_D, QT_TRANSLATE_NOOP("shortcuts", "Tool: Pencil"), ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT, "pencil_tool"); - defShrt(SHRT_TOOL_RUBBER, Qt::Key_R, QT_TRANSLATE_NOOP("shortcuts", "Tool: Eraser"), ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT, "eraser_tool"); + defShrt(SHRT_TOOL_POINTER, Qt::Key_A, QT_TRANSLATE_NOOP("shortcuts", "Tool: Pointer"), ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT + WAVE_SHRT + SCORE_SHRT, "pointer_tool"); + defShrt(SHRT_TOOL_PENCIL, Qt::Key_D, QT_TRANSLATE_NOOP("shortcuts", "Tool: Pencil"), ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT + WAVE_SHRT + SCORE_SHRT, "pencil_tool"); + defShrt(SHRT_TOOL_RUBBER, Qt::Key_R, QT_TRANSLATE_NOOP("shortcuts", "Tool: Eraser"), ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT + WAVE_SHRT + SCORE_SHRT, "eraser_tool"); + defShrt(SHRT_TOOL_PAN, Qt::Key_P, QT_TRANSLATE_NOOP("shortcuts", "Tool: Pan"), ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT + WAVE_SHRT, "pan_tool"); + defShrt(SHRT_TOOL_ZOOM, Qt::Key_Z, QT_TRANSLATE_NOOP("shortcuts", "Tool: Zoom"), ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT + WAVE_SHRT, "zoom_tool"); // piano roll & drum editor defShrt(SHRT_TOOL_LINEDRAW, Qt::Key_F, QT_TRANSLATE_NOOP("shortcuts", "Tool: Line Draw"), ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT, "line_draw_tool"); @@ -242,6 +244,9 @@ void initShortCuts() defShrt(SHRT_INSTRUMENT_STEP_UP, Qt::Key_Up, QT_TRANSLATE_NOOP("shortcuts", "Instrument/Cursor up"), DEDIT_SHRT, "instrument_up"); defShrt(SHRT_INSTRUMENT_STEP_DOWN, Qt::Key_Down, QT_TRANSLATE_NOOP("shortcuts", "Instrument/Cursor down"), DEDIT_SHRT, "instrument_down"); + // wave editor + defShrt(SHRT_TOOL_RANGE, Qt::Key_Y, QT_TRANSLATE_NOOP("shortcuts", "Tool: Range"), WAVE_SHRT, "range_tool"); + // arranger defShrt(SHRT_TOOL_SCISSORS, Qt::Key_S, QT_TRANSLATE_NOOP("shortcuts", "Tool: Scissor"), ARRANG_SHRT, "scissor_tool"); defShrt(SHRT_TOOL_GLUE, Qt::Key_G, QT_TRANSLATE_NOOP("shortcuts", "Tool: Glue"), ARRANG_SHRT, "glue_tool"); @@ -286,17 +291,17 @@ void initShortCuts() */ - defShrt(SHRT_SET_QUANT_1, Qt::Key_1, QT_TRANSLATE_NOOP("shortcuts", "Quantize: Set quantize to 1/1 note"), PROLL_SHRT, "midi_quant_1"); - defShrt(SHRT_SET_QUANT_2, Qt::Key_2, QT_TRANSLATE_NOOP("shortcuts", "Quantize: Set quantize to 1/2 note"), PROLL_SHRT, "midi_quant_2"); - defShrt(SHRT_SET_QUANT_3, Qt::Key_3, QT_TRANSLATE_NOOP("shortcuts", "Quantize: Set quantize to 1/4 note"), PROLL_SHRT, "midi_quant_3"); - defShrt(SHRT_SET_QUANT_4, Qt::Key_4, QT_TRANSLATE_NOOP("shortcuts", "Quantize: Set quantize to 1/8 note"), PROLL_SHRT, "midi_quant_4"); - defShrt(SHRT_SET_QUANT_5, Qt::Key_5, QT_TRANSLATE_NOOP("shortcuts", "Quantize: Set quantize to 1/16 note"), PROLL_SHRT, "midi_quant_5"); - defShrt(SHRT_SET_QUANT_6, Qt::Key_6, QT_TRANSLATE_NOOP("shortcuts", "Quantize: Set quantize to 1/32 note"), PROLL_SHRT, "midi_quant_6"); - defShrt(SHRT_SET_QUANT_7, Qt::Key_7, QT_TRANSLATE_NOOP("shortcuts", "Quantize: Set quantize to 1/64 note"), PROLL_SHRT, "midi_quant_7"); - - defShrt(SHRT_TOGGLE_TRIOL, Qt::Key_T, QT_TRANSLATE_NOOP("shortcuts", "Quantize: Toggle triol quantization"), PROLL_SHRT, "midi_quant_triol"); - defShrt(SHRT_TOGGLE_PUNCT, Qt::Key_Period, QT_TRANSLATE_NOOP("shortcuts", "Quantize: Toggle punctuation quantization"), PROLL_SHRT, "midi_quant_punct"); - defShrt(SHRT_TOGGLE_PUNCT2, Qt::Key_Comma, QT_TRANSLATE_NOOP("shortcuts", "Quantize: Toggle punctuation quantization (2)"), PROLL_SHRT, "midi_quant_punct2"); + defShrt(SHRT_SET_QUANT_1, Qt::Key_1, QT_TRANSLATE_NOOP("shortcuts", "Quantize: Set quantize to 1/1 note"), PROLL_SHRT + DEDIT_SHRT, "midi_quant_1"); + defShrt(SHRT_SET_QUANT_2, Qt::Key_2, QT_TRANSLATE_NOOP("shortcuts", "Quantize: Set quantize to 1/2 note"), PROLL_SHRT + DEDIT_SHRT, "midi_quant_2"); + defShrt(SHRT_SET_QUANT_3, Qt::Key_3, QT_TRANSLATE_NOOP("shortcuts", "Quantize: Set quantize to 1/4 note"), PROLL_SHRT + DEDIT_SHRT, "midi_quant_3"); + defShrt(SHRT_SET_QUANT_4, Qt::Key_4, QT_TRANSLATE_NOOP("shortcuts", "Quantize: Set quantize to 1/8 note"), PROLL_SHRT + DEDIT_SHRT, "midi_quant_4"); + defShrt(SHRT_SET_QUANT_5, Qt::Key_5, QT_TRANSLATE_NOOP("shortcuts", "Quantize: Set quantize to 1/16 note"), PROLL_SHRT + DEDIT_SHRT, "midi_quant_5"); + defShrt(SHRT_SET_QUANT_6, Qt::Key_6, QT_TRANSLATE_NOOP("shortcuts", "Quantize: Set quantize to 1/32 note"), PROLL_SHRT + DEDIT_SHRT, "midi_quant_6"); + defShrt(SHRT_SET_QUANT_7, Qt::Key_7, QT_TRANSLATE_NOOP("shortcuts", "Quantize: Set quantize to 1/64 note"), PROLL_SHRT + DEDIT_SHRT, "midi_quant_7"); + + defShrt(SHRT_TOGGLE_TRIOL, Qt::Key_T, QT_TRANSLATE_NOOP("shortcuts", "Quantize: Toggle triol quantization"), PROLL_SHRT + DEDIT_SHRT, "midi_quant_triol"); + defShrt(SHRT_TOGGLE_PUNCT, Qt::Key_Period, QT_TRANSLATE_NOOP("shortcuts", "Quantize: Toggle punctuation quantization"), PROLL_SHRT + DEDIT_SHRT, "midi_quant_punct"); + defShrt(SHRT_TOGGLE_PUNCT2, Qt::Key_Comma, QT_TRANSLATE_NOOP("shortcuts", "Quantize: Toggle punctuation quantization (2)"), PROLL_SHRT + DEDIT_SHRT, "midi_quant_punct2"); defShrt(SHRT_INSERT_AT_LOCATION, Qt::SHIFT + Qt::Key_Right, QT_TRANSLATE_NOOP("shortcuts", "Edit: Insert at location"), PROLL_SHRT, "midi_insert_at_loc"); defShrt(SHRT_INCREASE_LEN, Qt::CTRL + Qt::SHIFT + Qt::Key_Right, QT_TRANSLATE_NOOP("shortcuts", "Edit: Increase length"), PROLL_SHRT, "increase_len"); @@ -322,8 +327,10 @@ void initShortCuts() defShrt(SHRT_LM_EDIT_VALUE, Qt::CTRL + Qt::Key_E, QT_TRANSLATE_NOOP("shortcuts", "Edit Event Value"), LMEDIT_SHRT, "lm_edit_val"); defShrt(SHRT_LM_INS_KEY, Qt::CTRL + Qt::Key_K, QT_TRANSLATE_NOOP("shortcuts", "Insert Key"), LMEDIT_SHRT, "lm_ins_key"); - defShrt(SHRT_NEXT_MARKER, Qt::Key_F6, QT_TRANSLATE_NOOP("shortcuts", "Goto Next Marker"), ARRANG_SHRT, "me_sel_next"); - defShrt(SHRT_PREV_MARKER, Qt::Key_F5, QT_TRANSLATE_NOOP("shortcuts", "Goto Prev Marker"), ARRANG_SHRT, "me_sel_prev"); + // Since the marker window is always created at start, these are actually global + // because they are handled there, and affect the whole app. + defShrt(SHRT_NEXT_MARKER, Qt::Key_F6, QT_TRANSLATE_NOOP("shortcuts", "Goto Next Marker"), GLOBAL_SHRT, "me_sel_next"); + defShrt(SHRT_PREV_MARKER, Qt::Key_F5, QT_TRANSLATE_NOOP("shortcuts", "Goto Prev Marker"), GLOBAL_SHRT, "me_sel_prev"); } @@ -334,8 +341,8 @@ void initShortCuts() { DEDIT_SHRT, "Drumeditor" }, { LEDIT_SHRT, "List editor" }, { LMEDIT_SHRT, "List Mastertrack" }, -// { SCORE_SHRT, "Score editor" }, -// { WAVE_SHRT, "Wave editor" }, + { SCORE_SHRT, "Score editor" }, + { WAVE_SHRT, "Wave editor" }, { ALL_SHRT , "All categories" } }; diff --git a/muse2/muse/shortcuts.h b/muse2/muse/shortcuts.h index 8b7cdbef..309e9f9f 100644 --- a/muse2/muse/shortcuts.h +++ b/muse2/muse/shortcuts.h @@ -54,7 +54,7 @@ #define ALL_SHRT 1023 // All shortcuts #define INVIS_SHRT 1024 // Shortcuts not shown in the config-dialog. Hard-coded. To avoid conflicts -#define SHRT_NUM_OF_CATEGORIES 7 //Number of shortcut categories +#define SHRT_NUM_OF_CATEGORIES 9 //Number of shortcut categories namespace MusEGui { @@ -304,7 +304,9 @@ enum { SHRT_TOOL_POINTER, // SHRT_TOOL_PENCIL, SHRT_TOOL_RUBBER, - + SHRT_TOOL_PAN, + SHRT_TOOL_ZOOM, + // pianoroll and drum editor SHRT_TOOL_LINEDRAW, @@ -319,6 +321,9 @@ enum { SHRT_INSTRUMENT_STEP_DOWN, SHRT_INSTRUMENT_STEP_UP, + // wave editor + SHRT_TOOL_RANGE, + // arranger SHRT_TOOL_SCISSORS, SHRT_TOOL_GLUE, diff --git a/muse2/muse/synth.cpp b/muse2/muse/synth.cpp index e16e87d6..e04b55c8 100644 --- a/muse2/muse/synth.cpp +++ b/muse2/muse/synth.cpp @@ -30,6 +30,7 @@ #include <vector> #include <fcntl.h> #include <dlfcn.h> +#include <stdio.h> #include <QDir> #include <QString> @@ -203,7 +204,7 @@ static Synth* findSynth(const QString& sclass, const QString& label, Synth::Type (type == Synth::SYNTH_TYPE_END || type == (*i)->synthType()) ) return *i; } - printf("synthi type:%d class:%s label:%s not found\n", type, sclass.toLatin1().constData(), label.toLatin1().constData()); + fprintf(stderr, "synthi type:%d class:%s label:%s not found\n", type, sclass.toLatin1().constData(), label.toLatin1().constData()); return 0; } @@ -227,7 +228,7 @@ static SynthI* createSynthInstance(const QString& sclass, const QString& label, } } else - printf("createSynthInstance: synthi class:%s label:%s not found\n", sclass.toLatin1().constData(), label.toLatin1().constData()); + fprintf(stderr, "createSynthInstance: synthi class:%s label:%s not found\n", sclass.toLatin1().constData(), label.toLatin1().constData()); return si; } @@ -354,7 +355,7 @@ bool SynthI::putEvent(const MidiPlayEvent& ev) { if (MusEGlobal::midiOutputTrace) { - printf("MidiOut: Synth: <%s>: ", name().toLatin1().constData()); + fprintf(stderr, "MidiOut: Synth: <%s>: ", name().toLatin1().constData()); ev.dump(); } return _sif->putEvent(ev); @@ -561,13 +562,13 @@ void SynthI::deactivate3() //synthesizer->incInstances(-1); // Moved below by Tim. p3.3.14 if(MusEGlobal::debugMsg) - printf("SynthI::deactivate3 deleting _sif...\n"); + fprintf(stderr, "SynthI::deactivate3 deleting _sif...\n"); delete _sif; _sif = 0; if(MusEGlobal::debugMsg) - printf("SynthI::deactivate3 decrementing synth instances...\n"); + fprintf(stderr, "SynthI::deactivate3 decrementing synth instances...\n"); synthesizer->incInstances(-1); } @@ -602,7 +603,7 @@ void initMidiSynth() QDir pluginDir(s, QString("*.so")); // ddskrjo if (MusEGlobal::debugMsg) - printf("searching for software synthesizer in <%s>\n", s.toLatin1().constData()); + fprintf(stderr, "searching for software synthesizer in <%s>\n", s.toLatin1().constData()); if (pluginDir.exists()) { QFileInfoList list = pluginDir.entryInfoList(); QFileInfoList::iterator it=list.begin(); @@ -652,7 +653,7 @@ void initMidiSynth() ++it; } if (MusEGlobal::debugMsg) - printf("%zd soft synth found\n", MusEGlobal::synthis.size()); + fprintf(stderr, "%zd soft synth found\n", MusEGlobal::synthis.size()); } } @@ -1054,17 +1055,17 @@ iMPEvent MessSynthIF::getData(MidiPort* mp, MPEventList* el, iMPEvent i, unsigne int frame = evTime - abs(frameOffset); if (frame >= endPos) { - printf("frame > endPos!! frame = %d >= endPos %d, i->time() %d, frameOffset %d curPos=%d\n", frame, endPos, i->time(), frameOffset,curPos); + fprintf(stderr, "frame > endPos!! frame = %d >= endPos %d, i->time() %d, frameOffset %d curPos=%d\n", frame, endPos, i->time(), frameOffset,curPos); continue; } if (frame > curPos) { if (frame < (int) pos) - printf("should not happen: missed event %d\n", pos -frame); + fprintf(stderr, "should not happen: missed event %d\n", pos -frame); else { if (!_mess) - printf("should not happen - no _mess\n"); + fprintf(stderr, "should not happen - no _mess\n"); else { _mess->process(buffer, curPos-pos, frame - curPos); @@ -1084,7 +1085,7 @@ iMPEvent MessSynthIF::getData(MidiPort* mp, MPEventList* el, iMPEvent i, unsigne if (endPos - curPos) { if (!_mess) - printf("should not happen - no _mess\n"); + fprintf(stderr, "should not happen - no _mess\n"); else { _mess->process(buffer, curPos - off, endPos - curPos); diff --git a/muse2/muse/waveedit/wavecanvas.cpp b/muse2/muse/waveedit/wavecanvas.cpp index b9a006eb..80341554 100644 --- a/muse2/muse/waveedit/wavecanvas.cpp +++ b/muse2/muse/waveedit/wavecanvas.cpp @@ -51,6 +51,7 @@ #include <set> #include "app.h" +#include "icons.h" #include "xml.h" #include "wavecanvas.h" #include "event.h" @@ -656,6 +657,9 @@ void WaveCanvas::draw(QPainter& p, const QRect& r) p.drawLine(mx, my, mx, my2); } + if(drag == DRAG_ZOOM) + p.drawPixmap(mapFromGlobal(global_start), *zoomAtIcon); + //p.restore(); //p.setWorldMatrixEnabled(true); p.setWorldMatrixEnabled(wmtxen); @@ -848,30 +852,19 @@ void WaveCanvas::wheelEvent(QWheelEvent* ev) if (shift) { // scroll horizontally int delta = -ev->delta() / WHEEL_DELTA; int xpixelscale = 5*MusECore::fast_log10(rmapxDev(1)); - - if (xpixelscale <= 0) xpixelscale = 1; - int scrollstep = WHEEL_STEPSIZE * (delta); - ///if (ev->state() == Qt::ShiftModifier) - // if (((QInputEvent*)ev)->modifiers() == Qt::ShiftModifier) scrollstep = scrollstep / 10; - int newXpos = xpos + xpixelscale * scrollstep; - if (newXpos < 0) newXpos = 0; - - //setYPos(newYpos); emit horizontalScroll((unsigned)newXpos); - } else if (ctrl) { // zoom horizontally - emit horizontalZoom(ev->delta()>0, ev->x()); + emit horizontalZoom(ev->delta()>0, ev->globalPos()); } else { // scroll horizontally emit mouseWheelMoved(ev->delta() / 10); } - } //--------------------------------------------------------- @@ -891,7 +884,7 @@ bool WaveCanvas::mousePress(QMouseEvent* event) switch (_tool) { default: break; - case CursorTool: + case RangeTool: switch (button) { case Qt::LeftButton: if (mode == NORMAL) { @@ -1224,7 +1217,7 @@ void WaveCanvas::viewMouseDoubleClickEvent(QMouseEvent* event) // moveCanvasItems //--------------------------------------------------------- -MusECore::Undo WaveCanvas::moveCanvasItems(MusEGui::CItemList& items, int /*dp*/, int dx, DragType dtype) +MusECore::Undo WaveCanvas::moveCanvasItems(MusEGui::CItemList& items, int /*dp*/, int dx, DragType dtype, bool rasterize) { if(editor->parts()->empty()) return MusECore::Undo(); //return empty list @@ -1248,7 +1241,9 @@ MusECore::Undo WaveCanvas::moveCanvasItems(MusEGui::CItemList& items, int /*dp*/ int x = ci->pos().x() + dx; //int y = pitch2y(y2pitch(ci->pos().y()) + dp); int y = 0; - QPoint newpos = raster(QPoint(x, y)); + QPoint newpos = QPoint(x, y); + if(rasterize) + newpos = raster(newpos); // Test moving the item... WEvent* wevent = (WEvent*) ci; @@ -1256,7 +1251,7 @@ MusECore::Undo WaveCanvas::moveCanvasItems(MusEGui::CItemList& items, int /*dp*/ x = newpos.x(); if(x < 0) x = 0; - int nframe = MusEGlobal::tempomap.tick2frame(editor->rasterVal(MusEGlobal::tempomap.frame2tick(x))) - part->frame(); + int nframe = (rasterize ? MusEGlobal::tempomap.tick2frame(editor->rasterVal(MusEGlobal::tempomap.frame2tick(x))) : x) - part->frame(); if(nframe < 0) nframe = 0; int diff = nframe + event.lenFrame() - part->lenFrame(); @@ -1305,7 +1300,9 @@ MusECore::Undo WaveCanvas::moveCanvasItems(MusEGui::CItemList& items, int /*dp*/ int nx = x + dx; //int ny = pitch2y(y2pitch(y) + dp); int ny = 0; - QPoint newpos = raster(QPoint(nx, ny)); + QPoint newpos = QPoint(nx, ny); + if(rasterize) + newpos = raster(newpos); selectItem(ci, true); iDoneList idl; @@ -1317,7 +1314,7 @@ MusECore::Undo WaveCanvas::moveCanvasItems(MusEGui::CItemList& items, int /*dp*/ // 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); @@ -1351,7 +1348,7 @@ MusECore::Undo WaveCanvas::moveCanvasItems(MusEGui::CItemList& items, int /*dp*/ // called after moving an object //--------------------------------------------------------- -bool WaveCanvas::moveItem(MusECore::Undo& operations, MusEGui::CItem* item, const QPoint& pos, DragType dtype) +bool WaveCanvas::moveItem(MusECore::Undo& operations, MusEGui::CItem* item, const QPoint& pos, DragType dtype, bool rasterize) { WEvent* wevent = (WEvent*) item; MusECore::Event event = wevent->event(); @@ -1362,7 +1359,7 @@ bool WaveCanvas::moveItem(MusECore::Undo& operations, MusEGui::CItem* item, cons x = 0; MusECore::Part* part = wevent->part(); - int nframe = MusEGlobal::tempomap.tick2frame(editor->rasterVal(MusEGlobal::tempomap.frame2tick(x))) - part->frame(); + int nframe = (rasterize ? MusEGlobal::tempomap.tick2frame(editor->rasterVal(MusEGlobal::tempomap.frame2tick(x))) : x) - part->frame(); if (nframe < 0) nframe = 0; newEvent.setFrame(nframe); @@ -1384,9 +1381,11 @@ bool WaveCanvas::moveItem(MusECore::Undo& operations, MusEGui::CItem* item, cons // newItem(p, state) //--------------------------------------------------------- -MusEGui::CItem* WaveCanvas::newItem(const QPoint& p, int) +MusEGui::CItem* WaveCanvas::newItem(const QPoint& p, int key_modifiers) { - int frame = MusEGlobal::tempomap.tick2frame(editor->rasterVal1(MusEGlobal::tempomap.frame2tick(p.x()))); + int frame = p.x(); + if(!(key_modifiers & Qt::ShiftModifier)) + frame = MusEGlobal::tempomap.tick2frame(editor->rasterVal1(MusEGlobal::tempomap.frame2tick(frame))); int len = p.x() - frame; frame -= curPart->frame(); if (frame < 0) @@ -1402,9 +1401,11 @@ void WaveCanvas::newItem(MusEGui::CItem* item, bool noSnap) { WEvent* wevent = (WEvent*) item; MusECore::Event event = wevent->event(); + MusECore::Part* part = wevent->part(); + int pframe = part->frame(); int x = item->x(); - if (x<0) - x=0; + if (x<pframe) + x=pframe; int w = item->width(); if (!noSnap) { @@ -1416,8 +1417,9 @@ void WaveCanvas::newItem(MusEGui::CItem* item, bool noSnap) //w = editor->raster(); w = MusEGlobal::tempomap.tick2frame(editor->raster()); } - MusECore::Part* part = wevent->part(); - event.setFrame(x - part->frame()); + if (x<pframe) + x=pframe; + event.setFrame(x - pframe); event.setLenFrame(w); MusECore::Undo operations; @@ -1696,7 +1698,7 @@ void WaveCanvas::cmd(int cmd) double paramA = 0.0; switch (cmd) { case CMD_SELECT_ALL: // select all - if (tool() == MusEGui::CursorTool) + if (tool() == MusEGui::RangeTool) { if (!editor->parts()->empty()) { MusECore::iPart iBeg = editor->parts()->begin(); diff --git a/muse2/muse/waveedit/wavecanvas.h b/muse2/muse/waveedit/wavecanvas.h index 5ad836bc..10f75291 100644 --- a/muse2/muse/waveedit/wavecanvas.h +++ b/muse2/muse/waveedit/wavecanvas.h @@ -114,8 +114,8 @@ class WaveCanvas : 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); @@ -128,6 +128,8 @@ class WaveCanvas : public EventCanvas { int y2pitch(int) const; int pitch2y(int) const; + inline int y2height(int) const { return height(); } + inline int yItemOffset() const { return 0; } virtual void drawCanvas(QPainter&, const QRect&); virtual void itemPressed(const CItem*); virtual void itemReleased(const CItem*, const QPoint&); diff --git a/muse2/muse/waveedit/waveedit.cpp b/muse2/muse/waveedit/waveedit.cpp index 95443757..03a4d045 100644 --- a/muse2/muse/waveedit/waveedit.cpp +++ b/muse2/muse/waveedit/waveedit.cpp @@ -67,7 +67,7 @@ extern QColor readColor(MusECore::Xml& xml); namespace MusEGui { static int waveEditTools = MusEGui::PointerTool | MusEGui::PencilTool | MusEGui::RubberTool | - MusEGui::CutTool | MusEGui::CursorTool; + MusEGui::CutTool | MusEGui::RangeTool | PanTool | ZoomTool; int WaveEdit::_rasterInit = 96; int WaveEdit::colorModeInit = 0; @@ -298,7 +298,8 @@ WaveEdit::WaveEdit(MusECore::PartList* pl, QWidget* parent, const char* name) ymag->setFixedWidth(16); connect(canvas, SIGNAL(mouseWheelMoved(int)), this, SLOT(moveVerticalSlider(int))); connect(ymag, SIGNAL(valueChanged(int)), canvas, SLOT(setYScale(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(0, 0); @@ -334,8 +335,8 @@ WaveEdit::WaveEdit(MusECore::PartList* pl, QWidget* parent, const char* name) connect(MusEGlobal::song, SIGNAL(songChanged(MusECore::SongChangedFlags_t)), SLOT(songChanged1(MusECore::SongChangedFlags_t))); // For the wave editor, let's start with the operation range selection tool. - canvas->setTool(MusEGui::CursorTool); - tools2->set(MusEGui::CursorTool); + canvas->setTool(MusEGui::RangeTool); + tools2->set(MusEGui::RangeTool); setEventColorMode(colorMode); @@ -683,8 +684,16 @@ void WaveEdit::keyPressEvent(QKeyEvent* event) tools2->set(MusEGui::CutTool); return; } - else if (key == shortcuts[SHRT_TOOL_CURSOR].key) { - tools2->set(MusEGui::CursorTool); + 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_TOOL_RANGE].key) { + tools2->set(MusEGui::RangeTool); return; } else if (key == shortcuts[SHRT_EVENT_COLOR].key) { @@ -698,21 +707,11 @@ void WaveEdit::keyPressEvent(QKeyEvent* event) // TODO: New WaveCanvas: Convert some of these to use frames. else if (key == shortcuts[SHRT_ZOOM_IN].key) { - int offset = 0; - QPoint cp = canvas->mapFromGlobal(QCursor::pos()); - QPoint sp = mainw->mapFromGlobal(QCursor::pos()); - if(cp.x() >= 0 && cp.x() < canvas->width() && sp.y() >= 0 && sp.y() < mainw->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 = mainw->mapFromGlobal(QCursor::pos()); - if(cp.x() >= 0 && cp.x() < canvas->width() && sp.y() >= 0 && sp.y() < mainw->height()) - offset = cp.x(); - horizontalZoom(false, offset); + horizontalZoom(false, QCursor::pos()); return; } else if (key == shortcuts[SHRT_GOTO_CPOS].key) { @@ -783,7 +782,7 @@ void WaveEdit::moveVerticalSlider(int val) ymag->setValue(ymag->value() + val); } -void WaveEdit::horizontalZoom(bool zoom_in, int pos_offset) +void WaveEdit::horizontalZoom(bool zoom_in, const QPoint& glob_pos) { int mag = hscroll->mag(); int zoomlvl = ScrollScale::getQuickZoomLevel(mag); @@ -798,7 +797,19 @@ void WaveEdit::horizontalZoom(bool zoom_in, int pos_offset) zoomlvl--; } int newmag = ScrollScale::convertQuickZoomLevelToMag(zoomlvl); - hscroll->setMag(newmag, pos_offset); + + QPoint cp = canvas->mapFromGlobal(glob_pos); + QPoint sp = mainw->mapFromGlobal(glob_pos); + if(cp.x() >= 0 && cp.x() < canvas->width() && sp.y() >= 0 && sp.y() < mainw->height()) + hscroll->setMag(newmag, cp.x()); +} + +void WaveEdit::horizontalZoom(int mag, const QPoint& glob_pos) +{ + QPoint cp = canvas->mapFromGlobal(glob_pos); + QPoint sp = mainw->mapFromGlobal(glob_pos); + if(cp.x() >= 0 && cp.x() < canvas->width() && sp.y() >= 0 && sp.y() < mainw->height()) + hscroll->setMag(hscroll->mag() + mag, cp.x()); } //--------------------------------------------------------- diff --git a/muse2/muse/waveedit/waveedit.h b/muse2/muse/waveedit/waveedit.h index 54fc769a..0f4a4031 100644 --- a/muse2/muse/waveedit/waveedit.h +++ b/muse2/muse/waveedit/waveedit.h @@ -40,6 +40,7 @@ class QAction; class QResizeEvent; class QSlider; class QToolButton; +class QPoint; namespace MusECore { class PartList; @@ -101,7 +102,8 @@ class WaveEdit : public MidiEditor { public slots: void configChanged(); virtual void updateHScrollRange(); - void horizontalZoom(bool zoom_in, int pos_offset); + void horizontalZoom(bool zoom_in, const QPoint& glob_pos); + void horizontalZoom(int mag, const QPoint& glob_pos); void focusCanvas(); signals: diff --git a/muse2/muse/widgets/appearancebase.ui b/muse2/muse/widgets/appearancebase.ui index 3f270d36..b82ff182 100644 --- a/muse2/muse/widgets/appearancebase.ui +++ b/muse2/muse/widgets/appearancebase.ui @@ -23,7 +23,7 @@ </sizepolicy> </property> <property name="currentIndex"> - <number>2</number> + <number>0</number> </property> <widget class="QWidget" name="tab1"> <attribute name="title"> diff --git a/muse2/muse/widgets/canvas.cpp b/muse2/muse/widgets/canvas.cpp index 2091631a..326992eb 100644 --- a/muse2/muse/widgets/canvas.cpp +++ b/muse2/muse/widgets/canvas.cpp @@ -22,10 +22,12 @@ //========================================================= #include <stdio.h> +#include <math.h> #include "canvas.h" #include <QApplication> +#include <QDesktopWidget> #include <QMenu> #include <QPainter> #include <QCursor> @@ -33,9 +35,11 @@ #include <QKeyEvent> #include <QMouseEvent> #include <QWheelEvent> +#include <QRect> #include <vector> +#include "gconfig.h" #include "song.h" #include "event.h" #include "citem.h" @@ -43,6 +47,7 @@ #include "../marker/marker.h" #include "part.h" #include "fastlog.h" +#include "menutitleitem.h" #define ABS(x) ((x) < 0) ? -(x) : (x) @@ -68,8 +73,9 @@ Canvas::Canvas(QWidget* parent, int sx, int sy, const char* name) hscrollDir = HSCROLL_NONE; vscrollDir = VSCROLL_NONE; scrollTimer=NULL; + ignore_mouse_move = false; - scrollSpeed=10; // hardcoded scroll jump + scrollSpeed=30; // hardcoded scroll jump drag = DRAG_OFF; _tool = PointerTool; @@ -79,12 +85,20 @@ Canvas::Canvas(QWidget* parent, int sx, int sy, const char* name) curPart = NULL; curPartId = -1; curItem = NULL; + newCItem = NULL; connect(MusEGlobal::song, SIGNAL(posChanged(int, unsigned, bool)), this, SLOT(setPos(int, unsigned, bool))); } Canvas::~Canvas() { items.clearDelete(); + + if(newCItem) + { + if(newCItem->event().empty() && newCItem->part()) // Was it a new part, with no event? + delete newCItem->part(); + delete newCItem; + } } //--------------------------------------------------------- @@ -164,7 +178,7 @@ void Canvas::setPos(int idx, unsigned val, bool adjustScrollbar) //--------------------------------------------------------- void Canvas::draw(QPainter& p, const QRect& rect) - { +{ // printf("draw canvas %x virt %d\n", this, virt()); int x = rect.x(); @@ -175,7 +189,6 @@ void Canvas::draw(QPainter& p, const QRect& rect) std::vector<CItem*> list1; std::vector<CItem*> list2; - //std::vector<CItem*> list3; std::vector<CItem*> list4; if (virt()) { @@ -186,44 +199,6 @@ void Canvas::draw(QPainter& p, const QRect& rect) //--------------------------------------------------- iCItem to(items.lower_bound(x2)); - - /* - // Draw items from other parts behind all others. - // Only for items with events (not arranger parts). - for(iCItem i = items.begin(); i != to; ++i) - { - CItem* ci = i->second; - // NOTE Optimization: For each item call this once now, then use cached results later via cachedHasHiddenEvents(). - ci->part()->hasHiddenEvents(); - if(!ci->event().empty() && ci->part() != curPart) - drawItem(p, ci, rect); - } - - // Draw unselected parts behind selected. - for (iCItem i = items.begin(); i != to; ++i) - { - CItem* ci = i->second; - if((!ci->isSelected() && !ci->isMoving() && (ci->event().empty() || ci->part() == curPart)) - && !(ci->event().empty() && (ci->part()->events()->arefCount() > 1 || ci->part()->cachedHasHiddenEvents()))) // p4.0.29 - { - drawItem(p, ci, rect); - } - } - - // Draw selected parts in front of unselected. - for (iCItem i = items.begin(); i != to; ++i) - { - CItem* ci = i->second; - if(ci->isSelected() && !ci->isMoving() && (ci->event().empty() || ci->part() == curPart)) - //if((ci->isSelected() && !ci->isMoving() && (ci->event().empty() || ci->part() == curPart)) - // || (ci->event().empty() && (ci->part()->events()->arefCount() > 1 || ci->part()->cachedHasHiddenEvents()))) - { - drawItem(p, ci, rect); - } - } - */ - - // p4.0.29 for(iCItem i = items.begin(); i != to; ++i) { CItem* ci = i->second; @@ -240,11 +215,6 @@ void Canvas::draw(QPainter& p, const QRect& rect) // Draw selected parts in front of all others. if(ci->isSelected()) list4.push_back(ci); - // Draw clone parts, and parts with hidden events, in front of others all except selected. - //else if(ci->event().empty() && (ci->part()->events()->arefCount() > 1 || ci->part()->cachedHasHiddenEvents())) - // Draw clone parts in front of others all except selected. - //else if(ci->event().empty() && (ci->part()->events()->arefCount() > 1)) - // list3.push_back(ci); else // Draw unselected parts. list2.push_back(ci); @@ -257,21 +227,22 @@ void Canvas::draw(QPainter& p, const QRect& rect) sz = list2.size(); for(i = 0; i != sz; ++i) drawItem(p, list2[i], rect); - //sz = list3.size(); - //for(i = 0; i != sz; ++i) - // drawItem(p, list3[i], rect); sz = list4.size(); for(i = 0; i != sz; ++i) drawItem(p, list4[i], rect); + // Draw items being moved, a special way in their original location. to = moving.lower_bound(x2); for (iCItem i = moving.begin(); i != to; ++i) - { drawItem(p, i->second, rect); - } + // Draw special top item for new recordings etc. drawTopItem(p,rect); + // Draw special new item for first-time placement. + // It is not in the item list yet. It will be added when mouse released. + if(newCItem) + drawItem(p, newCItem, rect); } else { p.save(); @@ -308,47 +279,14 @@ void Canvas::draw(QPainter& p, const QRect& rect) y = 0; x2 = x + w; - drawCanvas(p, QRect(x, y, w, h)); + QRect new_rect(x, y, w, h); + drawCanvas(p, new_rect); p.restore(); //--------------------------------------------------- // draw Canvas Items //--------------------------------------------------- - /* - // Draw items from other parts behind all others. - // Only for items with events (not arranger parts). - for(iCItem i = items.begin(); i != items.end(); ++i) - { - CItem* ci = i->second; - // NOTE Optimization: For each item call this once now, then use cached results later via cachedHasHiddenEvents(). - ci->part()->hasHiddenEvents(); - if(!ci->event().empty() && ci->part() != curPart) - drawItem(p, ci, rect); - } - - // Draw unselected parts behind selected. - for (iCItem i = items.begin(); i != items.end(); ++i) { - CItem* ci = i->second; - if(!ci->isSelected() && !ci->isMoving() && (ci->event().empty() || ci->part() == curPart)) - { - drawItem(p, ci, rect); - } - } - - // Draw selected parts in front of unselected. - for (iCItem i = items.begin(); i != items.end(); ++i) { - CItem* ci = i->second; - if(ci->isSelected() && !ci->isMoving() && (ci->event().empty() || ci->part() == curPart)) - //if((ci->isSelected() && !ci->isMoving() && (ci->event().empty() || ci->part() == curPart)) - // || (ci->event().empty() && (ci->part()->events()->arefCount() > 1 || ci->part()->cachedHasHiddenEvents()))) - { - drawItem(p, ci, rect); - } - } - */ - - // p4.0.29 for(iCItem i = items.begin(); i != items.end(); ++i) { CItem* ci = i->second; @@ -365,11 +303,6 @@ void Canvas::draw(QPainter& p, const QRect& rect) // Draw selected parts in front of all others. if(ci->isSelected()) list4.push_back(ci); - // Draw clone parts, and parts with hidden events, in front of others all except selected. - //else if(ci->event().empty() && (ci->part()->events()->arefCount() > 1 || ci->part()->cachedHasHiddenEvents())) - // Draw clone parts in front of others all except selected. - //else if(ci->event().empty() && (ci->part()->events()->arefCount() > 1)) - // list3.push_back(ci); else // Draw unselected parts. list2.push_back(ci); @@ -382,18 +315,22 @@ void Canvas::draw(QPainter& p, const QRect& rect) sz = list2.size(); for(i = 0; i != sz; ++i) drawItem(p, list2[i], rect); - //sz = list3.size(); - //for(i = 0; i != sz; ++i) - // drawItem(p, list3[i], rect); sz = list4.size(); for(i = 0; i != sz; ++i) drawItem(p, list4[i], rect); - + + // Draw items being moved, a special way in their original location. for (iCItem i = moving.begin(); i != moving.end(); ++i) - { drawItem(p, i->second, rect); - } - drawTopItem(p, QRect(x,y,w,h)); + + // Draw special top item for new recordings etc. + drawTopItem(p, new_rect); + + // Draw special new item for first-time placement. + // It is not in the item list yet. It will be added when mouse released. + if(newCItem) + drawItem(p, newCItem, rect); + p.save(); setPainter(p); } @@ -407,14 +344,12 @@ void Canvas::draw(QPainter& p, const QRect& rect) p.setWorldMatrixEnabled(false); int my = mapy(y); - //int y2 = y + h; int my2 = mapy(y + h); MusECore::MarkerList* marker = MusEGlobal::song->marker(); for (MusECore::iMarker m = marker->begin(); m != marker->end(); ++m) { int xp = m->second.tick(); if (xp >= x && xp < x+w) { p.setPen(Qt::green); - //p.drawLine(xp, y, xp, y2); p.drawLine(mapx(xp), my, mapx(xp), my2); } } @@ -426,22 +361,22 @@ void Canvas::draw(QPainter& p, const QRect& rect) p.setPen(Qt::blue); int mx; if (pos[1] >= unsigned(x) && pos[1] < unsigned(x2)) { - //p.drawLine(pos[1], y, pos[1], y2); mx = mapx(pos[1]); p.drawLine(mx, my, mx, my2); } if (pos[2] >= unsigned(x) && pos[2] < unsigned(x2)) { - //p.drawLine(pos[2], y, pos[2], y2); mx = mapx(pos[2]); p.drawLine(mx, my, mx, my2); } p.setPen(Qt::red); if (pos[0] >= unsigned(x) && pos[0] < unsigned(x2)) { - //p.drawLine(pos[0], y, pos[0], y2); mx = mapx(pos[0]); p.drawLine(mx, my, mx, my2); } + if(drag == DRAG_ZOOM) + p.drawPixmap(mapFromGlobal(global_start), *zoomAtIcon); + //p.restore(); //p.setWorldMatrixEnabled(true); p.setWorldMatrixEnabled(wmtxen); @@ -457,7 +392,7 @@ void Canvas::draw(QPainter& p, const QRect& rect) } //--------------------------------------------------- - // draw moving items + // draw outlines of potential drop places of moving items //--------------------------------------------------- if(virt()) @@ -472,7 +407,7 @@ void Canvas::draw(QPainter& p, const QRect& rect) drawMoving(p, i->second, rect); setPainter(p); } - } +} #define WHEEL_STEPSIZE 40 #define WHEEL_DELTA 120 @@ -490,47 +425,29 @@ void Canvas::wheelEvent(QWheelEvent* ev) if (shift) { // scroll horizontally int delta = -ev->delta() / WHEEL_DELTA; int xpixelscale = 5*MusECore::fast_log10(rmapxDev(1)); - if (xpixelscale <= 0) xpixelscale = 1; - int scrollstep = WHEEL_STEPSIZE * (delta); - ///if (ev->state() == Qt::ShiftModifier) - // if (((QInputEvent*)ev)->modifiers() == Qt::ShiftModifier) scrollstep = scrollstep / 10; - int newXpos = xpos + xpixelscale * scrollstep; - if (newXpos < 0) newXpos = 0; - - //setYPos(newYpos); emit horizontalScroll((unsigned)newXpos); } else if (ctrl) { // zoom horizontally - emit horizontalZoom(ev->delta()>0, ev->x()); + emit horizontalZoom(ev->delta()>0, ev->globalPos()); } else { // scroll vertically int delta = ev->delta() / WHEEL_DELTA; int ypixelscale = rmapyDev(1); - if (ypixelscale <= 0) ypixelscale = 1; - int scrollstep = WHEEL_STEPSIZE * (-delta); - ///if (ev->state() == Qt::ShiftModifier) - // if (((QInputEvent*)ev)->modifiers() == Qt::ShiftModifier) scrollstep = scrollstep / 2; - int newYpos = ypos + ypixelscale * scrollstep; - if (newYpos < 0) newYpos = 0; - - //setYPos(newYpos); emit verticalScroll((unsigned)newYpos); - } - } void Canvas::redirectedWheelEvent(QWheelEvent* ev) @@ -562,7 +479,7 @@ void Canvas::selectItem(CItem* e, bool flag) // copy selection-List to moving-List //--------------------------------------------------------- -void Canvas::startMoving(const QPoint& pos, DragType) +void Canvas::startMoving(const QPoint& pos, DragType, bool rasterize) { for (iCItem i = items.begin(); i != items.end(); ++i) { if (i->second->isSelected()) { @@ -570,7 +487,7 @@ void Canvas::startMoving(const QPoint& pos, DragType) moving.add(i->second); } } - moveItems(pos, 0); + moveItems(pos, 0, rasterize); } //--------------------------------------------------------- @@ -580,13 +497,9 @@ void Canvas::startMoving(const QPoint& pos, DragType) // 2 move only vertical //--------------------------------------------------------- -void Canvas::moveItems(const QPoint& pos, int dir = 0, bool rasterize) +void Canvas::moveItems(const QPoint& pos, int dir, bool rasterize) { - int dp; - if(rasterize) - dp = y2pitch(pos.y()) - y2pitch(start.y()); - else - dp = pos.y() - start.y(); + int dp = y2pitch(pos.y()) - y2pitch(start.y()); int dx = pos.x() - start.x(); if (dir == 1) dp = 0; @@ -598,16 +511,12 @@ void Canvas::moveItems(const QPoint& pos, int dir = 0, bool rasterize) int nx = x + dx; int ny; QPoint mp; + ny = pitch2y(y2pitch(y) + dp); if(rasterize) - { - ny = pitch2y(y2pitch(y) + dp); mp = raster(QPoint(nx, ny)); - } - else - { - ny = y + dp; + else mp = QPoint(nx, ny); - } + if (i->second->mp() != mp) { i->second->setMp(mp); itemMoved(i->second, mp); @@ -626,6 +535,15 @@ void Canvas::viewKeyPressEvent(QKeyEvent* event) } //--------------------------------------------------------- +// viewKeyReleaseEvent +//--------------------------------------------------------- + +void Canvas::viewKeyReleaseEvent(QKeyEvent* event) + { + keyRelease(event); + } + +//--------------------------------------------------------- // viewMousePressEvent //--------------------------------------------------------- @@ -634,16 +552,13 @@ void Canvas::viewMousePressEvent(QMouseEvent* event) if (!mousePress(event)) return; - ///keyState = event->state(); - keyState = ((QInputEvent*)event)->modifiers(); + keyState = event->modifiers(); button = event->button(); - //printf("viewMousePressEvent buttons:%x mods:%x button:%x\n", (int)event->buttons(), (int)keyState, event->button()); // special events if right button is clicked while operations // like moving or drawing lasso is performed. - ///if (event->stateAfter() & Qt::RightButton) { - if (event->buttons() & Qt::RightButton & ~(event->button())) { + if (event->buttons() & Qt::RightButton & ~(button)) { //printf("viewMousePressEvent special buttons:%x mods:%x button:%x\n", (int)event->buttons(), (int)keyState, event->button()); switch (drag) { case DRAG_LASSO: @@ -660,15 +575,19 @@ void Canvas::viewMousePressEvent(QMouseEvent* event) } // ignore event if (another) button is already active: - ///if (keyState & (Qt::LeftButton|Qt::RightButton|Qt::MidButton)) { - if (event->buttons() & (Qt::LeftButton|Qt::RightButton|Qt::MidButton) & ~(event->button())) { + if (event->buttons() & (Qt::LeftButton|Qt::RightButton|Qt::MidButton) & ~(button)) { //printf("viewMousePressEvent ignoring buttons:%x mods:%x button:%x\n", (int)event->buttons(), (int)keyState, event->button()); return; } + bool alt = keyState & Qt::AltModifier; bool ctrl = keyState & Qt::ControlModifier; + start = event->pos(); - + ev_pos = start; + global_start = event->globalPos(); + ev_global_pos = global_start; + //--------------------------------------------------- // set curItem to item mouse is pointing // (if any) @@ -687,7 +606,6 @@ void Canvas::viewMousePressEvent(QMouseEvent* event) int w = rmapxDev(box.width()); int h = rmapyDev(box.height()); QRect r(x, y, w, h); - ///r.moveBy(i->second->pos().x(), i->second->pos().y()); r.translate(i->second->pos().x(), i->second->pos().y()); if (r.contains(start)) { if(i->second->isSelected()) @@ -707,14 +625,14 @@ void Canvas::viewMousePressEvent(QMouseEvent* event) curItem = ius->second; } - if (curItem && (event->button() == Qt::MidButton)) { + if (curItem && (button == Qt::MidButton)) { deleteItem(start); // changed from "start drag" to "delete" by flo93 drag = DRAG_DELETE; setCursor(); } - else if (event->button() == Qt::RightButton) { + else if (button == Qt::RightButton) { if (curItem) { - if (ctrl) { + if (ctrl && virt()) { // Non-virt width is meaningless, such as drums. drag = DRAG_RESIZE; setCursor(); int dx = start.x() - curItem->x(); @@ -745,20 +663,17 @@ void Canvas::viewMousePressEvent(QMouseEvent* event) } } } - else if (event->button() == Qt::LeftButton) { + else if (button == Qt::LeftButton) { switch (_tool) { case PointerTool: if (curItem) { itemPressed(curItem); - // Changed by T356. Alt is default reserved for moving the whole window in KDE. Changed to Shift-Alt. - // Hmm, nope, shift-alt is also reserved sometimes. Must find a way to bypass, - // why make user turn off setting? Left alone for now... - if (ctrl) + // Alt alone is usually reserved for moving a window in X11. Ignore shift + alt. + if (ctrl && !alt) drag = DRAG_COPY_START; - else if (alt) { + else if (ctrl && alt) drag = DRAG_CLONE_START; - } - else + else if (!ctrl && !alt) drag = DRAG_MOVE_START; } else @@ -774,18 +689,32 @@ void Canvas::viewMousePressEvent(QMouseEvent* event) case PencilTool: if (curItem) { - drag = DRAG_RESIZE; - setCursor(); - int dx = start.x() - curItem->x(); - curItem->setWidth(dx); - start.setX(curItem->x()); + if(!virt()) { // Non-virt width is meaningless, such as drums. + itemPressed(curItem); + // Alt alone is usually reserved for moving a window in X11. Ignore shift + alt. + if (ctrl && !alt) + drag = DRAG_COPY_START; + else if (ctrl && alt) + drag = DRAG_CLONE_START; + else if (!ctrl && !alt) + drag = DRAG_MOVE_START; + setCursor(); + break; + } + else { + drag = DRAG_RESIZE; + setCursor(); + int dx = start.x() - curItem->x(); + curItem->setWidth(dx); + start.setX(curItem->x()); + } } else { drag = DRAG_NEW; setCursor(); - curItem = newItem(start, event->modifiers()); + curItem = newItem(start, keyState); if (curItem) - items.add(curItem); + newCItem = curItem; else { drag = DRAG_OFF; setCursor(); @@ -798,6 +727,35 @@ void Canvas::viewMousePressEvent(QMouseEvent* event) redraw(); break; + case PanTool: + { + drag = DRAG_PAN; + if(MusEGlobal::config.borderlessMouse) + { + QRect r = QApplication::desktop()->screenGeometry(); + ignore_mouse_move = true; // Avoid recursion. + QCursor::setPos( QPoint(r.width()/2, r.height()/2) ); + } + setCursor(); + } + break; + + case ZoomTool: + { + drag = DRAG_ZOOM; + if(MusEGlobal::config.borderlessMouse) + { + QRect r = QApplication::desktop()->screenGeometry(); + ignore_mouse_move = true; // Avoid recursion. + QCursor::setPos( QPoint(r.width()/2, r.height()/2) ); + } + setCursor(); + // Update the small zoom drawing area + QPoint pt = mapFromGlobal(global_start); + update(pt.x(), pt.y(), zoomIcon->width(), zoomIcon->height()); + } + break; + default: break; } @@ -807,19 +765,22 @@ void Canvas::viewMousePressEvent(QMouseEvent* event) void Canvas::scrollTimerDone() { //printf("Canvas::scrollTimerDone drag:%d doScroll:%d\n", drag, doScroll); - - if (drag != DRAG_OFF && doScroll) + if (doScroll && drag != DRAG_OFF && drag != DRAG_ZOOM) { //printf("Canvas::scrollTimerDone drag != DRAG_OFF && doScroll\n"); - + int modifiers = QApplication::keyboardModifiers(); + bool ctrl = modifiers & Qt::ControlModifier; + bool meta = modifiers & Qt::MetaModifier; + bool alt = modifiers & Qt::AltModifier; + bool right_button = QApplication::mouseButtons() & Qt::RightButton; + bool scrollDoResize = ((!ctrl && !right_button) || meta || alt) && virt(); // Non-virt width is meaningless, such as drums. + int dx = 0; + int dy = 0; bool doHMove = false; bool doVMove = false; - int hoff = rmapx(xOffset())+mapx(xorg)-1; - int curxpos; switch(hscrollDir) { case HSCROLL_RIGHT: - hoff += scrollSpeed; switch(drag) { case DRAG_NEW: @@ -833,102 +794,83 @@ void Canvas::scrollTimerDone() case DRAG_MOVE: case DRAG_COPY: case DRAG_CLONE: - emit horizontalScrollNoLimit(hoff); + case DRAG_PAN: + emit horizontalScrollNoLimit(xpos + scrollSpeed); canScrollLeft = true; - ev_pos.setX(rmapxDev(rmapx(ev_pos.x()) + scrollSpeed)); + dx = rmapxDev(scrollSpeed); + ev_pos.setX(ev_pos.x() + dx); doHMove = true; break; default: if(canScrollRight) { - curxpos = xpos; - emit horizontalScroll(hoff); + int curxpos = xpos; + emit horizontalScroll(xpos + scrollSpeed); if(xpos <= curxpos) - { canScrollRight = false; - } else { canScrollLeft = true; - ev_pos.setX(rmapxDev(rmapx(ev_pos.x()) + scrollSpeed)); + dx = rmapxDev(scrollSpeed); + ev_pos.setX(ev_pos.x() + dx); doHMove = true; } } - else - { - } break; } break; case HSCROLL_LEFT: if(canScrollLeft) { - curxpos = xpos; - hoff -= scrollSpeed; - emit horizontalScroll(hoff); + int curxpos = xpos; + emit horizontalScroll(xpos - scrollSpeed); if(xpos >= curxpos) - { canScrollLeft = false; - } else { canScrollRight = true; - ev_pos.setX(rmapxDev(rmapx(ev_pos.x()) - scrollSpeed)); + dx = -rmapxDev(scrollSpeed); + ev_pos.setX(ev_pos.x() + dx); doHMove = true; } } - else - { - } break; default: break; } - int voff = rmapy(yOffset())+mapy(yorg); - int curypos; switch(vscrollDir) { case VSCROLL_DOWN: if(canScrollDown) { - curypos = ypos; - voff += scrollSpeed; - emit verticalScroll(voff); + int curypos = ypos; + emit verticalScroll(ypos + scrollSpeed); if(ypos <= curypos) - { canScrollDown = false; - } else { canScrollUp = true; - ev_pos.setY(rmapyDev(rmapy(ev_pos.y()) + scrollSpeed)); + dy = rmapyDev(scrollSpeed); + ev_pos.setY(ev_pos.y() + dy); doVMove = true; } } - else - { - } break; case VSCROLL_UP: if(canScrollUp) { - curypos = ypos; - voff -= scrollSpeed; - emit verticalScroll(voff); + int curypos = ypos; + emit verticalScroll(ypos - scrollSpeed); if(ypos >= curypos) - { canScrollUp = false; - } else { canScrollDown = true; - ev_pos.setY(rmapyDev(rmapy(ev_pos.y()) - scrollSpeed)); + dy = -rmapyDev(scrollSpeed); + ev_pos.setY(ev_pos.y() + dy); doVMove = true; } } - else - { - } break; default: break; @@ -965,13 +907,41 @@ void Canvas::scrollTimerDone() lasso = QRect(start.x(), start.y(), dist.x(), dist.y()); redraw(); break; + case DRAG_NEW: + if(newCItem) + { + if((doHMove && !scrollDoResize) || doVMove) + { + int nx = newCItem->x(); + int ny = newCItem->y(); + if(doHMove && !scrollDoResize) + nx += dx; + if(nx < 0) + nx = 0; + if(doVMove) + ny += dy; + if(ny < 0) + ny = 0; + newCItem->move(QPoint(nx, ny)); + } + if(scrollDoResize && doHMove) + { + int w = ev_pos.x() - newCItem->x(); + if(w < 1) + w = 1; + newCItem->setWidth(w); + } + redraw(); + } + break; + case DRAG_RESIZE: - if (dist.x()) { - if (dist.x() < 1) - curItem->setWidth(1); - else - curItem->setWidth(dist.x()); + if (doHMove) { + int w = ev_pos.x() - curItem->x(); + if(w < 1) + w = 1; + curItem->setWidth(w); redraw(); } break; @@ -980,51 +950,63 @@ void Canvas::scrollTimerDone() } //printf("Canvas::scrollTimerDone starting scrollTimer: Currently active?%d\n", scrollTimer->isActive()); - // p3.3.43 Make sure to yield to other events (for up to 3 seconds), otherwise other events - // take a long time to reach us, causing scrolling to take a painfully long time to stop. - // FIXME: Didn't help at all. - //qApp->processEvents(); - // No, try up to 100 ms for each yield. - //qApp->processEvents(100); - // - //scrollTimer->start( 40, TRUE ); // X ms single-shot timer - // OK, changing the timeout from 40 to 80 helped. - //scrollTimer->start( 80, TRUE ); // X ms single-shot timer + // Make sure to yield to other events, otherwise other events take a long time to reach us, + // causing scrolling to take a painfully long time to stop. Try up to 100 ms for each yield: + //qApp->processEvents(100); // FIXME: Didn't help at all. scrollTimer->setSingleShot(true); - scrollTimer->start(80); + scrollTimer->start(80); // OK, setting a timeout 80 helped. } else { //printf("Canvas::scrollTimerDone !(drag != DRAG_OFF && doScroll) deleting scrollTimer\n"); - delete scrollTimer; scrollTimer=NULL; } } - //--------------------------------------------------------- // viewMouseMoveEvent //--------------------------------------------------------- void Canvas::viewMouseMoveEvent(QMouseEvent* event) { + if(ignore_mouse_move) + { + ignore_mouse_move = false; + event->accept(); + return; + } + //fprintf(stderr, "xpos=%d xorg=%d xmag=%d event->x=%d ->gx:%d mapx(xorg)=%d rmapx0=%d xOffset=%d rmapx(xOffset()=%d\n", + // xpos, xorg, xmag, event->x(), event->globalX(), mapx(xorg), rmapx(0), xOffset(), rmapx(xOffset())); + //fprintf(stderr, "ypos=%d yorg=%d ymag=%d event->y=%d ->gy:%d mapy(yorg)=%d rmapy0=%d yOffset=%d rmapy(yOffset()=%d\n", + // ypos, yorg, ymag, event->y(), event->globalY(), mapy(yorg), rmapy(0), yOffset(), rmapy(yOffset())); + + QRect screen_rect = QApplication::desktop()->screenGeometry(); + QPoint screen_center = QPoint(screen_rect.width()/2, screen_rect.height()/2); + QPoint glob_dist = event->globalPos() - ev_global_pos; + QPoint glob_zoom_dist = MusEGlobal::config.borderlessMouse ? (event->globalPos() - screen_center) : glob_dist; + QPoint last_dist = event->pos() - ev_pos; - ev_pos = event->pos(); - QPoint dist = ev_pos - start; - int ax = ABS(rmapx(dist.x())); - int ay = ABS(rmapy(dist.y())); - bool moving = (ax >= 2) || (ay > 2); + ev_pos = event->pos(); + QPoint dist = ev_pos - start; + int ax = ABS(rmapx(dist.x())); + int ay = ABS(rmapy(dist.y())); + bool moving = (ax >= 2) || (ay > 2); + int modifiers = event->modifiers(); + bool ctrl = modifiers & Qt::ControlModifier; + bool shift = modifiers & Qt::ShiftModifier; + bool meta = modifiers & Qt::MetaModifier; + bool alt = modifiers & Qt::AltModifier; + bool right_button = event->buttons() & Qt::RightButton; // set scrolling variables: doScroll, scrollRight - if (drag != DRAG_OFF) { - - + // No auto scroll in zoom mode or normal pan mode. + if (drag != DRAG_OFF && drag != DRAG_ZOOM && (drag != DRAG_PAN || !MusEGlobal::config.borderlessMouse)) { int ex = rmapx(event->x())+mapx(0); - if(ex < 40 && canScrollLeft) - hscrollDir = HSCROLL_LEFT; + if(ex < 15 && (canScrollLeft || drag == DRAG_PAN)) + hscrollDir = (drag == DRAG_PAN ? HSCROLL_RIGHT : HSCROLL_LEFT); else - if(ex > (width() - 40)) + if(ex > (width() - 15)) switch(drag) { case DRAG_NEW: @@ -1038,25 +1020,28 @@ void Canvas::viewMouseMoveEvent(QMouseEvent* event) case DRAG_MOVE: case DRAG_COPY: case DRAG_CLONE: - hscrollDir = HSCROLL_RIGHT; + case DRAG_PAN: + hscrollDir = (drag == DRAG_PAN ? HSCROLL_LEFT : HSCROLL_RIGHT); break; default: if(canScrollRight) - hscrollDir = HSCROLL_RIGHT; + hscrollDir = (drag == DRAG_PAN ? HSCROLL_LEFT : HSCROLL_RIGHT); else hscrollDir = HSCROLL_NONE; break; } else hscrollDir = HSCROLL_NONE; + int ey = rmapy(event->y())+mapy(0); - if(ey < 15 && canScrollUp) - vscrollDir = VSCROLL_UP; + if(ey < 15 && (canScrollUp || drag == DRAG_PAN)) + vscrollDir = (drag == DRAG_PAN ? VSCROLL_DOWN : VSCROLL_UP); else - if(ey > (height() - 15) && canScrollDown) - vscrollDir = VSCROLL_DOWN; + if(ey > (height() - 15) && (canScrollDown || drag == DRAG_PAN)) + vscrollDir = (drag == DRAG_PAN ? VSCROLL_UP : VSCROLL_DOWN); else vscrollDir = VSCROLL_NONE; + if(hscrollDir != HSCROLL_NONE || vscrollDir != VSCROLL_NONE) { doScroll=true; @@ -1064,7 +1049,6 @@ void Canvas::viewMouseMoveEvent(QMouseEvent* event) { scrollTimer= new QTimer(this); connect( scrollTimer, SIGNAL(timeout()), SLOT(scrollTimerDone()) ); - //scrollTimer->start( 0, TRUE ); // single-shot timer scrollTimer->setSingleShot(true); // single-shot timer scrollTimer->start(0); } @@ -1090,14 +1074,11 @@ void Canvas::viewMouseMoveEvent(QMouseEvent* event) drag = DRAG_LASSO; setCursor(); // proceed with DRAG_LASSO: - case DRAG_LASSO: { lasso = QRect(start.x(), start.y(), dist.x(), dist.y()); - // printf("xorg=%d xmag=%d event->x=%d, mapx(xorg)=%d rmapx0=%d xOffset=%d rmapx(xOffset()=%d\n", // xorg, xmag, event->x(),mapx(xorg), rmapx(0), xOffset(),rmapx(xOffset())); - } redraw(); break; @@ -1149,50 +1130,123 @@ void Canvas::viewMouseMoveEvent(QMouseEvent* event) else dt = MOVE_CLONE; - startMoving(ev_pos, dt); + startMoving(ev_pos, dt, !(keyState & Qt::ShiftModifier)); break; case DRAG_MOVE: case DRAG_COPY: case DRAG_CLONE: - if(!scrollTimer) - moveItems(ev_pos, 0); + moveItems(ev_pos, 0, !shift); break; case DRAGX_MOVE: case DRAGX_COPY: case DRAGX_CLONE: if(!scrollTimer) - moveItems(ev_pos, 1); + moveItems(ev_pos, 1, false); break; case DRAGY_MOVE: case DRAGY_COPY: case DRAGY_CLONE: if(!scrollTimer) - moveItems(ev_pos, 2); + moveItems(ev_pos, 2, false); break; case DRAG_NEW: + if(newCItem) { + if (last_dist.x()) { + if(((ctrl || right_button) && !meta && !alt) || !virt()) // Non-virt width is meaningless, such as drums. + { + int nx = ev_pos.x() - newCItem->width(); // Keep the cursor at the right edge. + if(nx < 0) + nx = 0; + if(!shift) + { + nx = raster(QPoint(nx, 0)).x(); // 0 is dummy, we want only x + if(nx < 0) + nx = 0; + } + newCItem->move(QPoint(nx, newCItem->y())); + } + else + { + int w = ev_pos.x() - newCItem->x(); + if(w < 1) + w = 1; + newCItem->setWidth(w); + } + } + if (last_dist.y()) { + int x = newCItem->x(); + int y = ev_pos.y(); + int ny = pitch2y(y2pitch(y)) - yItemOffset(); + QPoint pt = QPoint(x, ny); + newCItem->move(pt); + newCItem->setHeight(y2height(y)); + itemMoved(newCItem, pt); + } + if (last_dist.x() || last_dist.y()) + redraw(); + } + break; + case DRAG_RESIZE: - if (dist.x()) { - if (dist.x() < 1) - curItem->setWidth(1); - else - curItem->setWidth(dist.x()); + if (last_dist.x()) { + int w = ev_pos.x() - curItem->x(); + if(w < 1) + w = 1; + curItem->setWidth(w); redraw(); } break; + case DRAG_DELETE: deleteItem(ev_pos); break; + case DRAG_PAN: + { + bool changed = false; + if((!shift || (shift && ctrl)) && glob_zoom_dist.x() != 0 && (!doScroll || hscrollDir == HSCROLL_NONE)) // Don't interfere if auto-scrolling + { + emit horizontalScroll(xpos - glob_zoom_dist.x()); + changed = true; + } + if((!ctrl || (shift && ctrl)) && glob_zoom_dist.y() != 0 && (!doScroll || vscrollDir == VSCROLL_NONE)) // Don't interfere if auto-scrolling + { + emit verticalScroll(ypos - glob_zoom_dist.y()); + changed = true; + } + if(MusEGlobal::config.borderlessMouse && changed) + { + ignore_mouse_move = true; // Avoid recursion. + QCursor::setPos(screen_center); + } + } + break; + + case DRAG_ZOOM: + if(glob_zoom_dist.x() != 0) + emit horizontalZoom(glob_zoom_dist.x(), global_start); + //if(glob_zoom_dist.y() != 0) + // emit verticalZoom(glob_zoom_dist.y(), global_start); // TODO + if(MusEGlobal::config.borderlessMouse && (glob_zoom_dist.x() != 0 || glob_zoom_dist.y() != 0)) + { + ignore_mouse_move = true; // Avoid recursion. + QCursor::setPos(screen_center); + } + break; + case DRAG_OFF: break; } - - mouseMove(event); + + ev_global_pos = event->globalPos(); + + if(drag != DRAG_ZOOM && (drag != DRAG_PAN || !MusEGlobal::config.borderlessMouse)) + mouseMove(event); } //--------------------------------------------------------- @@ -1200,19 +1254,18 @@ void Canvas::viewMouseMoveEvent(QMouseEvent* event) //--------------------------------------------------------- void Canvas::viewMouseReleaseEvent(QMouseEvent* event) - { +{ doScroll = false; canScrollLeft = true; canScrollRight = true; canScrollUp = true; canScrollDown = true; - if (event->buttons() & (Qt::LeftButton|Qt::RightButton|Qt::MidButton) & ~(event->button())) { + if (event->buttons() & (Qt::LeftButton|Qt::RightButton|Qt::MidButton) & ~(event->button())) return; - } QPoint pos = event->pos(); - bool ctrl = ((QInputEvent*)event)->modifiers() & Qt::ControlModifier; - bool shift = ((QInputEvent*)event)->modifiers() & Qt::ShiftModifier; + bool ctrl = event->modifiers() & Qt::ControlModifier; + bool shift = event->modifiers() & Qt::ShiftModifier; bool redrawFlag = false; switch (drag) { @@ -1224,10 +1277,8 @@ void Canvas::viewMouseReleaseEvent(QMouseEvent* event) curPartId = curPart->sn(); curPartChanged(); } - if (!ctrl) deselectAll(); - if (!shift) { //Select or deselect only the clicked item selectItem(curItem, !(ctrl && curItem->isSelected())); } @@ -1243,40 +1294,47 @@ void Canvas::viewMouseReleaseEvent(QMouseEvent* event) itemReleased(curItem, curItem->pos()); break; case DRAG_COPY: - endMoveItems(pos, MOVE_COPY, 0); + endMoveItems(pos, MOVE_COPY, 0, !shift); break; case DRAGX_COPY: - endMoveItems(pos, MOVE_COPY, 1); + endMoveItems(pos, MOVE_COPY, 1, false); break; case DRAGY_COPY: - endMoveItems(pos, MOVE_COPY, 2); + endMoveItems(pos, MOVE_COPY, 2, false); break; case DRAG_MOVE: - endMoveItems(pos, MOVE_MOVE, 0); + endMoveItems(pos, MOVE_MOVE, 0, !shift); break; case DRAGX_MOVE: - endMoveItems(pos, MOVE_MOVE, 1); + endMoveItems(pos, MOVE_MOVE, 1, false); break; case DRAGY_MOVE: - endMoveItems(pos, MOVE_MOVE, 2); + endMoveItems(pos, MOVE_MOVE, 2, false); break; case DRAG_CLONE: - endMoveItems(pos, MOVE_CLONE, 0); + endMoveItems(pos, MOVE_CLONE, 0, !shift); break; case DRAGX_CLONE: - endMoveItems(pos, MOVE_CLONE, 1); + endMoveItems(pos, MOVE_CLONE, 1, false); break; case DRAGY_CLONE: - endMoveItems(pos, MOVE_CLONE, 2); + endMoveItems(pos, MOVE_CLONE, 2, false); break; case DRAG_OFF: break; case DRAG_RESIZE: - resizeItem(curItem, false, ctrl); + resizeItem(curItem, shift, ctrl); break; case DRAG_NEW: - newItem(curItem, false); - redrawFlag = true; + if(newCItem) + { + items.add(newCItem); + curItem = newCItem; + newCItem = NULL; + itemReleased(curItem, curItem->pos()); + newItem(curItem, shift); + redrawFlag = true; + } break; case DRAG_LASSO_START: lasso.setRect(-1, -1, -1, -1); @@ -1297,15 +1355,49 @@ void Canvas::viewMouseReleaseEvent(QMouseEvent* event) case DRAG_DELETE: break; + + case DRAG_PAN: + if(MusEGlobal::config.borderlessMouse) + { + pos = global_start; + ignore_mouse_move = true; // Avoid recursion. + QCursor::setPos(global_start); + } + break; + + case DRAG_ZOOM: + if(MusEGlobal::config.borderlessMouse) + { + pos = global_start; + ignore_mouse_move = true; // Avoid recursion. + QCursor::setPos(global_start); + } + break; } //printf("Canvas::viewMouseReleaseEvent setting drag to DRAG_OFF\n"); + + // Just in case it was somehow forgotten: + if(newCItem) + { + if(newCItem->event().empty() && newCItem->part()) // Was it a new part, with no event? + delete newCItem->part(); + delete newCItem; + newCItem = NULL; + } + + if(drag == DRAG_ZOOM) // Update the small zoom drawing area + { + drag = DRAG_OFF; + QPoint pt = mapFromGlobal(global_start); + update(pt.x(), pt.y(), zoomIcon->width(), zoomIcon->height()); + } drag = DRAG_OFF; if (redrawFlag) redraw(); setCursor(); mouseRelease(pos); - } +} //--------------------------------------------------------- // selectLasso @@ -1330,7 +1422,6 @@ void Canvas::selectLasso(bool toggle) int w = rmapxDev(box.width()); int h = rmapyDev(box.height()); QRect r(x, y, w, h); - ///r.moveBy(i->second->pos().x(), i->second->pos().y()); r.translate(i->second->pos().x(), i->second->pos().y()); if (r.intersects(lasso)) { selectItem(i->second, !(toggle && i->second->isSelected())); @@ -1339,8 +1430,6 @@ void Canvas::selectLasso(bool toggle) } } - - if (n) { updateSelection(); redraw(); @@ -1385,7 +1474,6 @@ void Canvas::deleteItem(const QPoint& p) int w = rmapxDev(box.width()); int h = rmapyDev(box.height()); QRect r(x, y, w, h); - ///r.moveBy(i->second->pos().x(), i->second->pos().y()); r.translate(i->second->pos().x(), i->second->pos().y()); if (r.contains(p)) { if (deleteItem(i->second)) { @@ -1431,13 +1519,28 @@ void Canvas::setCursor() case DRAG_MOVE: case DRAG_COPY: case DRAG_CLONE: - QWidget::setCursor(QCursor(Qt::SizeAllCursor)); + // Bug in KDE cursor theme? On some distros this cursor is actually another version of a closed hand! From 'net: + // "It might be a problem in the distribution as Qt uses the cursor that is provided by X.org/xcursor extension with name "size_all". + // We fixed this issue by setting the KDE cursor theme to "System theme" " + QWidget::setCursor(QCursor(Qt::SizeAllCursor)); break; case DRAG_RESIZE: QWidget::setCursor(QCursor(Qt::SizeHorCursor)); break; + case DRAG_PAN: + if(MusEGlobal::config.borderlessMouse) + QWidget::setCursor(QCursor(Qt::BlankCursor)); // Hide it. + else + QWidget::setCursor(QCursor(Qt::ClosedHandCursor)); + break; + + case DRAG_ZOOM: + if(MusEGlobal::config.borderlessMouse) + QWidget::setCursor(QCursor(Qt::BlankCursor)); // Hide it. + break; + case DRAG_DELETE: case DRAG_COPY_START: case DRAG_CLONE_START: @@ -1465,6 +1568,12 @@ void Canvas::setCursor() case AutomationTool: QWidget::setCursor(QCursor(Qt::PointingHandCursor)); break; + case PanTool: + QWidget::setCursor(QCursor(Qt::OpenHandCursor)); + break; + case ZoomTool: + QWidget::setCursor(QCursor(*zoomAtIcon, 0, 0)); + break; default: QWidget::setCursor(QCursor(Qt::ArrowCursor)); break; @@ -1483,6 +1592,15 @@ void Canvas::keyPress(QKeyEvent* event) } //--------------------------------------------------------- +// keyRelease +//--------------------------------------------------------- + +void Canvas::keyRelease(QKeyEvent* event) + { + event->ignore(); + } + +//--------------------------------------------------------- // isSingleSelection //--------------------------------------------------------- @@ -1507,25 +1625,34 @@ int Canvas::selectionSize() //--------------------------------------------------------- // genCanvasPopup +// Add the list of available tools to a popup menu +// menu parameter can be NULL meaning create a menu here //--------------------------------------------------------- -QMenu* Canvas::genCanvasPopup() +QMenu* Canvas::genCanvasPopup(QMenu* menu) { if (canvasTools == 0) return 0; - QMenu* canvasPopup = new QMenu(this); + QMenu* r_menu = menu; + if(!r_menu) + r_menu = new QMenu(this); QAction* act0 = 0; - for (unsigned i = 0; i < 9; ++i) { + r_menu->addAction(new MenuTitleItem(tr("Tools:"), r_menu)); + + for (unsigned i = 0; i < gNumberOfTools; ++i) { if ((canvasTools & (1 << i))==0) continue; - QAction* act = canvasPopup->addAction(QIcon(**toolList[i].icon), tr(toolList[i].tip)); - act->setData(1<<i); // ddskrjo + QAction* act = r_menu->addAction(QIcon(**toolList[i].icon), tr(toolList[i].tip)); + act->setData(TOOLS_ID_BASE + i); + act->setCheckable(true); + act->setChecked((1 << i) == _tool); if (!act0) act0 = act; } - canvasPopup->setActiveAction(act0); - return canvasPopup; + if(!menu) // Don't interefere with supplied menu's current item + r_menu->setActiveAction(act0); + return r_menu; } //--------------------------------------------------------- @@ -1534,8 +1661,13 @@ QMenu* Canvas::genCanvasPopup() void Canvas::canvasPopup(int n) { - setTool(n); - emit toolChanged(n); + if(n >= TOOLS_ID_BASE) + { + n -= TOOLS_ID_BASE; + int t = 1 << n; + setTool(t); + emit toolChanged(t); + } } void Canvas::setCurrentPart(MusECore::Part* part) diff --git a/muse2/muse/widgets/canvas.h b/muse2/muse/widgets/canvas.h index e85d3db3..d6859a14 100644 --- a/muse2/muse/widgets/canvas.h +++ b/muse2/muse/widgets/canvas.h @@ -34,6 +34,7 @@ #include <QKeyEvent> class QMenu; +class QPoint; namespace MusEGui { @@ -43,17 +44,19 @@ namespace MusEGui { class Canvas : public View { Q_OBJECT - int canvasTools; QTimer *scrollTimer; bool doScroll; int scrollSpeed; - + QPoint ev_pos; + QPoint ev_global_pos; + bool ignore_mouse_move; bool canScrollLeft; bool canScrollRight; bool canScrollUp; bool canScrollDown; + protected: enum DragMode { DRAG_OFF, DRAG_NEW, @@ -65,6 +68,7 @@ class Canvas : public View { DRAGX_CLONE, DRAGY_CLONE, DRAG_DELETE, DRAG_RESIZE, DRAG_LASSO_START, DRAG_LASSO, + DRAG_PAN, DRAG_ZOOM }; enum DragType { @@ -78,15 +82,22 @@ class Canvas : public View { VSCROLL_NONE, VSCROLL_UP, VSCROLL_DOWN }; + enum MenuIdBase { + TOOLS_ID_BASE=10000 + }; + CItemList items; CItemList moving; + CItem* newCItem; CItem* curItem; MusECore::Part* curPart; int curPartId; + int canvasTools; DragMode drag; QRect lasso; QPoint start; + QPoint global_start; Tool _tool; unsigned pos[3]; @@ -99,14 +110,16 @@ class Canvas : public View { void setCursor(); virtual void viewKeyPressEvent(QKeyEvent* event); + virtual void viewKeyReleaseEvent(QKeyEvent* event); virtual void viewMousePressEvent(QMouseEvent* event); virtual void viewMouseMoveEvent(QMouseEvent*); virtual void viewMouseReleaseEvent(QMouseEvent*); virtual void draw(QPainter&, const QRect&); virtual void wheelEvent(QWheelEvent* e); - virtual bool mousePress(QMouseEvent*) { return true; } virtual void keyPress(QKeyEvent*); + virtual void keyRelease(QKeyEvent*); + virtual bool mousePress(QMouseEvent*) { return true; } virtual void mouseMove(QMouseEvent* event) = 0; virtual void mouseRelease(const QPoint&) {} virtual void drawCanvas(QPainter&, const QRect&) = 0; @@ -118,6 +131,8 @@ class Canvas : public View { virtual QPoint raster(const QPoint&) const = 0; virtual int y2pitch(int) const = 0; //CDW virtual int pitch2y(int) const = 0; //CDW + virtual int y2height(int) const = 0; + virtual int yItemOffset() const = 0; virtual CItem* newItem(const QPoint&, int state) = 0; virtual void resizeItem(CItem*, bool noSnap=false, bool ctrl=false) = 0; @@ -140,7 +155,7 @@ class Canvas : public View { Implementing class is responsible for creating a popup to be shown when the user rightclicks an empty region of the canvas \return A QPopupMenu* */ - QMenu* genCanvasPopup(); + QMenu* genCanvasPopup(QMenu* menu = 0); /*! \brief Virtual member @@ -162,10 +177,9 @@ class Canvas : public View { virtual void deleteItem(const QPoint&); // moving - void startMoving(const QPoint&, DragType); - - void moveItems(const QPoint&, int dir, bool rasterize = true); - virtual void endMoveItems(const QPoint&, DragType, int dir) = 0; + void startMoving(const QPoint&, DragType, bool rasterize = true); + void moveItems(const QPoint&, int dir = 0, bool rasterize = true); + virtual void endMoveItems(const QPoint&, DragType, int dir, bool rasterize = true) = 0; virtual void selectLasso(bool toggle); @@ -186,7 +200,8 @@ class Canvas : public View { void verticalScroll(unsigned); void horizontalScroll(unsigned); void horizontalScrollNoLimit(unsigned); - void horizontalZoom(bool zoom_in, int pos_offset); + void horizontalZoom(bool zoom_in, const QPoint& glob_pos); + void horizontalZoom(int mag, const QPoint& glob_pos); void curPartHasChanged(MusECore::Part*); public: diff --git a/muse2/muse/widgets/citem.cpp b/muse2/muse/widgets/citem.cpp index 4c830223..93c8046c 100644 --- a/muse2/muse/widgets/citem.cpp +++ b/muse2/muse/widgets/citem.cpp @@ -37,13 +37,12 @@ CItem::CItem() CItem::CItem(const QPoint&p, const QRect& r) { + _part = NULL; _pos = p; _bbox = r; _isMoving = false; } -// Changed by Tim. p3.3.20 -//CItem::CItem(MusECore::Event e, Part* p) CItem::CItem(const MusECore::Event& e, MusECore::Part* p) { _event = e; diff --git a/muse2/muse/widgets/genset.cpp b/muse2/muse/widgets/genset.cpp index 0f07428e..52be3d8a 100644 --- a/muse2/muse/widgets/genset.cpp +++ b/muse2/muse/widgets/genset.cpp @@ -221,6 +221,7 @@ void GlobalSettingsConfig::updateSettings() lmbDecreasesCheckBox->setChecked(MusEGlobal::config.leftMouseButtonCanDecrease); rangeMarkerWithoutMMBCheckBox->setChecked(MusEGlobal::config.rangeMarkerWithoutMMB); smartFocusCheckBox->setChecked(MusEGlobal::config.smartFocus); + borderlessMouseCheckBox->setChecked(MusEGlobal::config.borderlessMouse); velocityPerNoteCheckBox->setChecked(MusEGlobal::config.velocityPerNote); addHiddenCheckBox->setChecked(MusEGlobal::config.addHiddenTracks); @@ -340,6 +341,7 @@ void GlobalSettingsConfig::apply() MusEGlobal::config.leftMouseButtonCanDecrease = lmbDecreasesCheckBox->isChecked(); MusEGlobal::config.rangeMarkerWithoutMMB = rangeMarkerWithoutMMBCheckBox->isChecked(); MusEGlobal::config.smartFocus = smartFocusCheckBox->isChecked(); + MusEGlobal::config.borderlessMouse = borderlessMouseCheckBox->isChecked(); MusEGlobal::config.velocityPerNote = velocityPerNoteCheckBox->isChecked(); MusEGlobal::config.addHiddenTracks = addHiddenCheckBox->isChecked(); diff --git a/muse2/muse/widgets/gensetbase.ui b/muse2/muse/widgets/gensetbase.ui index 021272bd..8b1cc28d 100644 --- a/muse2/muse/widgets/gensetbase.ui +++ b/muse2/muse/widgets/gensetbase.ui @@ -7,7 +7,7 @@ <x>0</x> <y>0</y> <width>544</width> - <height>593</height> + <height>622</height> </rect> </property> <property name="windowTitle"> @@ -23,7 +23,7 @@ </sizepolicy> </property> <property name="currentIndex"> - <number>3</number> + <number>0</number> </property> <widget class="QWidget" name="TabPage"> <attribute name="title"> @@ -1334,6 +1334,13 @@ Adjusts responsiveness of audio controls and <string>Behavior</string> </property> <layout class="QGridLayout" name="gridLayout7"> + <item row="12" column="0"> + <widget class="QLabel" name="label_7"> + <property name="text"> + <string>Track height</string> + </property> + </widget> + </item> <item row="0" column="0"> <widget class="QLabel" name="TextLabel1"> <property name="text"> @@ -1563,7 +1570,7 @@ left button behave like the middle button in such areas.</string> <item row="10" column="0" colspan="2"> <widget class="QLabel" name="label_6"> <property name="text"> - <string>Show midi velocity graphs per-note</string> + <string>Show newly created midi velocity graphs per-note</string> </property> </widget> </item> @@ -1574,7 +1581,7 @@ left button behave like the middle button in such areas.</string> </property> </widget> </item> - <item row="12" column="1"> + <item row="13" column="1"> <spacer name="verticalSpacer_2"> <property name="orientation"> <enum>Qt::Vertical</enum> @@ -1587,14 +1594,7 @@ left button behave like the middle button in such areas.</string> </property> </spacer> </item> - <item row="11" column="0"> - <widget class="QLabel" name="label_7"> - <property name="text"> - <string>Track height</string> - </property> - </widget> - </item> - <item row="11" column="2"> + <item row="12" column="2"> <widget class="QSpinBox" name="trackHeight"> <property name="suffix"> <string> px</string> @@ -1610,6 +1610,39 @@ left button behave like the middle button in such areas.</string> </property> </widget> </item> + <item row="11" column="2"> + <widget class="QCheckBox" name="borderlessMouseCheckBox"> + <property name="toolTip"> + <string>Enable borderless mouse. +For certain functions like zoom/pan. +Disable to use an alternate standard + method. +</string> + </property> + <property name="whatsThis"> + <string>Enable borderless mouse. +For certain functions like zoom. +Disable to use an alternate standard + method.</string> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="11" column="0" colspan="2"> + <widget class="QLabel" name="label_8"> + <property name="toolTip"> + <string/> + </property> + <property name="whatsThis"> + <string/> + </property> + <property name="text"> + <string>Borderless zoom/pan mouse (else use alternate method)</string> + </property> + </widget> + </item> </layout> </widget> </item> @@ -1721,8 +1754,8 @@ left button behave like the middle button in such areas.</string> <rect> <x>0</x> <y>0</y> - <width>72</width> - <height>16</height> + <width>96</width> + <height>26</height> </rect> </property> <layout class="QHBoxLayout" name="horizontalLayout_3"> diff --git a/muse2/muse/widgets/musewidgetsplug.cpp b/muse2/muse/widgets/musewidgetsplug.cpp index 90eec237..c6fdc999 100644 --- a/muse2/muse/widgets/musewidgetsplug.cpp +++ b/muse2/muse/widgets/musewidgetsplug.cpp @@ -234,7 +234,9 @@ MusEGlobal::GlobalConfigValues config = { true, // addHiddenTracks true, // unhideTracks MusEGlobal::PREFER_NEW, // drumTrackPreference - true // smartFocus + true, // smartFocus + 20, // trackHeight + true // borderlessMouse }; //--------------------------------------------------------- diff --git a/muse2/muse/widgets/pitchlabel.cpp b/muse2/muse/widgets/pitchlabel.cpp index 1ab5aa8e..17c92048 100644 --- a/muse2/muse/widgets/pitchlabel.cpp +++ b/muse2/muse/widgets/pitchlabel.cpp @@ -44,8 +44,9 @@ PitchLabel::PitchLabel(QWidget* parent, const char* name) setMidLineWidth(3); setValue(0); //int fw = style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, this); // ddskrjo 0 - int fw = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); + int fw = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); setIndent(fw); + //setContentsMargins(0,0,0,0); } //--------------------------------------------------------- @@ -65,10 +66,10 @@ QSize PitchLabel::sizeHint() const { QFontMetrics fm(font()); //int fw = style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, this); // ddskrjo 0 - int fw = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); + int fw = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); int h = fm.height() + fw * 2; // int w = 2 + fm.width(QString("A#8")) + fw * 4; - int w = 2 + fm.width(QString("-9999")) + fw * 4; // must display 14Bit controller values + int w = fm.width(QString("-9999")) + fw * 2; // must display 14Bit controller values return QSize(w, h).expandedTo(QApplication::globalStrut()); } diff --git a/muse2/muse/widgets/poslabel.cpp b/muse2/muse/widgets/poslabel.cpp index c6c7ddfe..58e3c323 100644 --- a/muse2/muse/widgets/poslabel.cpp +++ b/muse2/muse/widgets/poslabel.cpp @@ -53,12 +53,10 @@ PosLabel::PosLabel(QWidget* parent, const char* name) setFrameStyle(WinPanel | Sunken); setLineWidth(2); setMidLineWidth(3); - //int fw = style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, this); // ddskrjo 0 int fw = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); setIndent(fw); - //setContentsMargins(0,0,0,0); // REMOVE Tim. Or keep and remove above three lines. - + //setContentsMargins(0,0,0,0); updateValue(); } @@ -70,7 +68,7 @@ QSize PosLabel::sizeHint() const { QFontMetrics fm(font()); //int fw = style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, this); // ddskrjo 0 - int fw = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); + int fw = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); int h = fm.height() + fw * 2; int w; if (_smpte) diff --git a/muse2/muse/widgets/scrollscale.cpp b/muse2/muse/widgets/scrollscale.cpp index d1f54ce0..fcf36e1b 100644 --- a/muse2/muse/widgets/scrollscale.cpp +++ b/muse2/muse/widgets/scrollscale.cpp @@ -44,10 +44,15 @@ namespace MusEGui { void ScrollScale::setScale ( int val, int pos_offset ) { + int mag_max = convertQuickZoomLevelToMag(zoomLevels-1); + if(val < 0) + val = 0; + else if(val > mag_max) + val = mag_max; int off = offset(); int old_scale_val = scaleVal; if ( invers ) - val = convertQuickZoomLevelToMag(zoomLevels-1) - val; + val = mag_max - val; double min, max; if ( scaleMin < 0 ) min = 1.0/ ( -scaleMin ); @@ -60,7 +65,7 @@ void ScrollScale::setScale ( int val, int pos_offset ) max = double ( scaleMax ); double diff = max-min; - double fkt = double ( val ) /double(convertQuickZoomLevelToMag(zoomLevels-1)); + double fkt = double ( val ) /double(mag_max); double v = ( pow ( logbase, fkt )-1 ) / ( logbase-1 ); double scale; if ( invers ) @@ -91,7 +96,7 @@ void ScrollScale::setScale ( int val, int pos_offset ) scale = scaleMin; } #endif -// printf("scaleMin %d scaleMax %d val=%d emit scaleVal=%d\n", scaleMin, scaleMax, val, scaleVal); + //fprintf(stderr, "scaleMin %d scaleMax %d val=%d emit scaleVal=%d\n", scaleMin, scaleMax, val, scaleVal); emit scaleChanged ( scaleVal ); if ( !noScale ) setRange ( minVal, maxVal ); diff --git a/muse2/muse/widgets/tb1.cpp b/muse2/muse/widgets/tb1.cpp index 2198bbb4..fb14c7a3 100644 --- a/muse2/muse/widgets/tb1.cpp +++ b/muse2/muse/widgets/tb1.cpp @@ -36,7 +36,7 @@ namespace MusEGui { -static int rasterTable[] = { +static int gArrangerRasterTable[] = { //------ 8 4 2 1, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 1, 6, 12, 24, 48, 96, 192, 384, 768, 1536, @@ -61,15 +61,12 @@ Toolbar1::Toolbar1(QWidget* parent, int r, bool sp) setObjectName("Pos/Snap/Solo-tools"); pitch = 0; showPitch = sp; - // ORCAN - FIXME: Check this: - //setHorizontalStretchable(false); - //setHorizontalPolicy(QSizePolicy::Minimum); - //setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred); solo = new QToolButton(); solo->setText(tr("Solo")); solo->setCheckable(true); solo->setFocusPolicy(Qt::NoFocus); + //solo->setContentsMargins(0,0,0,0); addWidget(solo); //--------------------------------------------------- @@ -79,14 +76,13 @@ Toolbar1::Toolbar1(QWidget* parent, int r, bool sp) QLabel* label = new QLabel(tr("Cursor")); label->setAlignment(Qt::AlignRight|Qt::AlignVCenter); label->setIndent(3); + //label->setContentsMargins(0,0,0,0); addWidget(label); pos = new PosLabel(0, "pos"); - ///pos->setFixedHeight(22); addWidget(pos); if (showPitch) { pitch = new PitchLabel(0); pitch->setEnabled(false); - ///pitch->setFixedHeight(22); addWidget(pitch); } @@ -96,6 +92,7 @@ Toolbar1::Toolbar1(QWidget* parent, int r, bool sp) raster = new LabelCombo(tr("Snap"), 0); raster->setFocusPolicy(Qt::TabFocus); + //raster->setContentsMargins(0,0,0,0); rlist = new QTableWidget(10, 3); rlist->verticalHeader()->setDefaultSectionSize(22); @@ -103,7 +100,7 @@ Toolbar1::Toolbar1(QWidget* parent, int r, bool sp) rlist->setSelectionMode(QAbstractItemView::SingleSelection); rlist->verticalHeader()->hide(); rlist->horizontalHeader()->hide(); - + //rlist->setContentsMargins(0,0,0,0); rlist->setMinimumWidth(96); raster->setView(rlist); @@ -113,12 +110,9 @@ Toolbar1::Toolbar1(QWidget* parent, int r, bool sp) rlist->setItem(i, j, new QTableWidgetItem(tr(rasterStrings[i + j * 10]))); setRaster(r); - + //setContentsMargins(0,0,0,0); addWidget(raster); - // FIXME: Not working right. - ///raster->setFixedHeight(38); - connect(raster, SIGNAL(activated(int)), SLOT(_rasterChanged(int))); connect(solo, SIGNAL(toggled(bool)), SIGNAL(soloChanged(bool))); pos->setEnabled(false); @@ -128,12 +122,14 @@ Toolbar1::Toolbar1(QWidget* parent, int r, bool sp) // rasterChanged //--------------------------------------------------------- -void Toolbar1::_rasterChanged(int /*i*/) -//void Toolbar1::_rasterChanged(int r, int c) +void Toolbar1::_rasterChanged(int) { - emit rasterChanged(rasterTable[rlist->currentRow() + rlist->currentColumn() * 10]); - //parentWidget()->setFocus(); - //emit rasterChanged(rasterTable[r + c * 10]); + int rast = gArrangerRasterTable[rlist->currentRow() + rlist->currentColumn() * 10]; + emit rasterChanged(rast); + // FIXME: HACK: Force the thing to show the right item. For some reason it won't stay on the left or right columns. + raster->blockSignals(true); + setRaster(rast); + raster->blockSignals(false); } @@ -181,8 +177,8 @@ void Toolbar1::setTime(unsigned val) void Toolbar1::setRaster(int val) { - for (unsigned i = 0; i < sizeof(rasterTable)/sizeof(*rasterTable); i++) { - if (val == rasterTable[i]) { + for (unsigned i = 0; i < sizeof(gArrangerRasterTable)/sizeof(*gArrangerRasterTable); i++) { + if (val == gArrangerRasterTable[i]) { raster->setCurrentIndex(i); return; } diff --git a/muse2/muse/widgets/tools.cpp b/muse2/muse/widgets/tools.cpp index da3f4d01..0bac4b10 100644 --- a/muse2/muse/widgets/tools.cpp +++ b/muse2/muse/widgets/tools.cpp @@ -52,27 +52,38 @@ const char* infoDraw = QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "select Drawing const char* infoMute = QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "select Muting Tool:\n" "click on part to mute/unmute"); const char* infoAutomation = QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "Manipulate automation"); -const char* infoCursor = QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "Cursor tool"); +const char* infoCursor = QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "select Cursor (tracker mode) tool:\n" + "with the cursor tool you can:\n" + " navigate with arrow keys\n" + " use VBNM to place notes\n" + " change step with 0 and 9"); +const char* infoRange = QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "select Range Tool"); +const char* infoPan = QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "select Panning Tool"); +const char* infoZoom = QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "select Zoom Tool"); ToolB toolList[] = { {&pointerIcon, QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "pointer"), infoPointer }, {&pencilIcon, QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "pencil"), infoPencil }, {&deleteIcon, QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "eraser"), infoDel }, {&cutIcon, QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "cutter"), infoCut }, - {¬e1Icon, QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "score"), infoScore }, {&glueIcon, QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "glue"), infoGlue }, + {&cursorIcon, QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "range"), infoRange }, + {&openHandIcon, QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "pan"), infoPan }, + {&zoomIcon, QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "zoom"), infoZoom }, + {¬e1Icon, QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "score"), infoScore }, {&quantIcon, QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "quantize"), infoQuant }, {&drawIcon, QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "draw"), infoDraw }, {&editmuteIcon, QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "mute parts"), infoMute }, {&drawIcon, QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "edit automation"),infoAutomation}, - {&cursorIcon, QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "cursor (tracker mode)\nNavigate with arrow keys\nUse VBNM to place notes\nChange step with 0 and 9"), infoCursor}, + {&cursorIcon, QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "cursor"), infoCursor} }; +const unsigned gNumberOfTools = sizeof(toolList) / sizeof(ToolB); + //--------------------------------------------------------- // EditToolBar //--------------------------------------------------------- -//EditToolBar::EditToolBar(QMainWindow* parent, int tools, const char*) EditToolBar::EditToolBar(QWidget* parent, int tools, const char*) : QToolBar(tr("Edit Tools"), parent) { diff --git a/muse2/muse/widgets/tools.h b/muse2/muse/widgets/tools.h index 71e63558..598a5955 100644 --- a/muse2/muse/widgets/tools.h +++ b/muse2/muse/widgets/tools.h @@ -39,16 +39,20 @@ enum Tool { PencilTool=2, RubberTool=4, CutTool=8, - ScoreTool=16, - GlueTool=32, - QuantTool=64, - DrawTool=128, - MuteTool=256, - AutomationTool=512, - CursorTool=1024 + GlueTool=16, + RangeTool=32, + PanTool=64, + ZoomTool=128, + ScoreTool=256, + QuantTool=512, + DrawTool=1024, + MuteTool=2048, + AutomationTool=4096, + CursorTool=8192 }; -const int arrangerTools = PointerTool | PencilTool | RubberTool | CutTool | GlueTool | MuteTool | AutomationTool; +const int arrangerTools = PointerTool | PencilTool | RubberTool | CutTool | GlueTool | MuteTool | + AutomationTool | PanTool | ZoomTool; struct ToolB { QPixmap** icon; @@ -57,6 +61,7 @@ struct ToolB { }; extern ToolB toolList[]; +extern const unsigned gNumberOfTools; //--------------------------------------------------------- // EditToolBar diff --git a/muse2/muse/widgets/view.cpp b/muse2/muse/widgets/view.cpp index fb53be46..e8bb1d89 100644 --- a/muse2/muse/widgets/view.cpp +++ b/muse2/muse/widgets/view.cpp @@ -420,6 +420,15 @@ void View::keyPressEvent(QKeyEvent* event) } //--------------------------------------------------------- +// keyReleaseEvent +//--------------------------------------------------------- + +void View::keyReleaseEvent(QKeyEvent* event) + { + viewKeyReleaseEvent(event); + } + +//--------------------------------------------------------- // viewKeyPressEvent //--------------------------------------------------------- @@ -429,6 +438,15 @@ void View::viewKeyPressEvent(QKeyEvent* event) } //--------------------------------------------------------- +// viewKeyReleaseEvent +//--------------------------------------------------------- + +void View::viewKeyReleaseEvent(QKeyEvent* event) + { + event->ignore(); + } + +//--------------------------------------------------------- // mousePressEvent //--------------------------------------------------------- diff --git a/muse2/muse/widgets/view.h b/muse2/muse/widgets/view.h index 30f234bb..6db63abe 100644 --- a/muse2/muse/widgets/view.h +++ b/muse2/muse/widgets/view.h @@ -58,6 +58,7 @@ class View : public QWidget { int xmag, ymag; virtual void keyPressEvent(QKeyEvent* event); + virtual void keyReleaseEvent(QKeyEvent* event); virtual void mousePressEvent(QMouseEvent* event); virtual void mouseDoubleClickEvent(QMouseEvent* event); virtual void mouseMoveEvent(QMouseEvent* event); @@ -78,6 +79,7 @@ class View : public QWidget { virtual void resizeEvent(QResizeEvent*); virtual void viewKeyPressEvent(QKeyEvent*); + virtual void viewKeyReleaseEvent(QKeyEvent*); virtual void viewMousePressEvent(QMouseEvent*) {} virtual void viewMouseDoubleClickEvent(QMouseEvent*) {} virtual void viewMouseMoveEvent(QMouseEvent*) {} |