summaryrefslogtreecommitdiff
path: root/muse2/muse/midiedit/drumedit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'muse2/muse/midiedit/drumedit.cpp')
-rw-r--r--muse2/muse/midiedit/drumedit.cpp202
1 files changed, 196 insertions, 6 deletions
diff --git a/muse2/muse/midiedit/drumedit.cpp b/muse2/muse/midiedit/drumedit.cpp
index 4d7fa906..7a86f010 100644
--- a/muse2/muse/midiedit/drumedit.cpp
+++ b/muse2/muse/midiedit/drumedit.cpp
@@ -61,6 +61,8 @@
#include "gconfig.h"
#include "functions.h"
#include "helper.h"
+#include "popupmenu.h"
+#include "menutitleitem.h"
#include "widgets/function_dialogs/quantize.h"
namespace MusEGui {
@@ -455,7 +457,7 @@ DrumEdit::DrumEdit(MusECore::PartList* pl, QWidget* parent, const char* name, un
//---------------------------------------------------
split1 = new MusEGui::Splitter(Qt::Vertical, mainw, "split1");
- QPushButton* ctrl = new QPushButton(tr("ctrl"), mainw);
+ ctrl = new QPushButton(tr("ctrl"), mainw);
ctrl->setObjectName("Ctrl");
ctrl->setFont(MusEGlobal::config.fonts[3]);
ctrl->setFocusPolicy(Qt::NoFocus);
@@ -598,7 +600,7 @@ DrumEdit::DrumEdit(MusECore::PartList* pl, QWidget* parent, const char* name, un
connect(info, SIGNAL(returnPressed()), SLOT(focusCanvas()));
connect(info, SIGNAL(escapePressed()), SLOT(focusCanvas()));
- connect(ctrl, SIGNAL(clicked()), SLOT(addCtrl()));
+ connect(ctrl, SIGNAL(clicked()), SLOT(addCtrlClicked()));
QClipboard* cb = QApplication::clipboard();
connect(cb, SIGNAL(dataChanged()), SLOT(clipboardChanged()));
@@ -1220,12 +1222,201 @@ void DrumEdit::selectionChanged()
}
//---------------------------------------------------------
+// ctrlPopupTriggered
+//---------------------------------------------------------
+
+void DrumEdit::ctrlPopupTriggered(QAction* act)
+{
+ // TODO Merge most of this with duplicate code in piano roll,
+ // maybe by putting it in a new function near populateMidiCtrlMenu.
+
+ if(!act || (act->data().toInt() == -1))
+ return;
+
+ int newCtlNum = -1;
+ MusECore::Part* part = curCanvasPart();
+ MusECore::MidiTrack* track = (MusECore::MidiTrack*)(part->track());
+ int channel = track->outChannel();
+ MusECore::MidiPort* port = &MusEGlobal::midiPorts[track->outPort()];
+ int curDrumPitch = curDrumInstrument();
+ bool isDrum = track->type() == MusECore::Track::DRUM;
+ bool isNewDrum = track->type() == MusECore::Track::NEW_DRUM;
+ MusECore::MidiInstrument* instr = port->instrument();
+ MusECore::MidiControllerList* mcl = instr->controller();
+
+ MusECore::MidiCtrlValListList* cll = port->controller();
+ int min = channel << 24;
+ int max = min + 0x1000000;
+
+ int rv = act->data().toInt();
+
+ if (rv == max) { // special case velocity
+ newCtlNum = MusECore::CTRL_VELOCITY;
+ }
+ else if (rv == max + 1) { // add new instrument controller
+
+ PopupMenu * ctrlSubPop = new PopupMenu(this, true); // true = enable stay open
+ ctrlSubPop->addAction(new MenuTitleItem(tr("Instrument-defined"), ctrlSubPop));
+
+ //
+ // populate popup with all controllers available for
+ // current instrument
+ //
+
+ for (MusECore::iMidiController ci = mcl->begin(); ci != mcl->end(); ++ci)
+ {
+ int num = ci->second->num();
+ if((num & 0xff) == 0xff)
+ {
+ if (isDrum && curDrumPitch!=-1)
+ num = (num & ~0xff) + MusEGlobal::drumMap[curDrumPitch].anote;
+ else if (isNewDrum && curDrumPitch!=-1)
+ num = (num & ~0xff) + curDrumPitch; //FINDMICH does this work?
+ else // dont show drum specific controller if not a drum track
+ continue;
+ }
+
+ if(cll->find(channel, num) == cll->end())
+ ctrlSubPop->addAction(MusECore::midiCtrlNumString(num, true) + ci->second->name())->setData(num);
+ }
+
+ // Don't allow editing instrument if it's a synth
+ if(!port->device() || port->device()->deviceType() != MusECore::MidiDevice::SYNTH_MIDI)
+ ctrlSubPop->addAction(QIcon(*midi_edit_instrumentIcon), tr("Edit instrument ..."))->setData(max + 2);
+
+ QAction *act2 = ctrlSubPop->exec(ctrl->mapToGlobal(QPoint(0,0)));
+ if (act2)
+ {
+ int rv2 = act2->data().toInt();
+
+ if (rv2 == max + 2) // edit instrument
+ MusEGlobal::muse->startEditInstrument();
+ else // select new instrument control
+ {
+ MusECore::MidiController* c;
+ for (MusECore::iMidiController ci = mcl->begin(); ci != mcl->end(); ++ci)
+ {
+ c = ci->second;
+ int num = c->num();
+ if (isDrum && ((num & 0xff) == 0xff) && curDrumPitch!=-1)
+ num = (num & ~0xff) + MusEGlobal::drumMap[curDrumPitch].anote;
+ else if (isNewDrum && ((num & 0xff) == 0xff) && curDrumPitch!=-1)
+ num = (num & ~0xff) + curDrumPitch; //FINDMICHJETZT does this work?
+
+ if(num != rv2)
+ continue;
+
+ if(cll->find(channel, num) == cll->end())
+ {
+ MusECore::MidiCtrlValList* vl = new MusECore::MidiCtrlValList(num);
+
+ cll->add(channel, vl);
+ newCtlNum = c->num();
+ }
+ else
+ newCtlNum = c->num();
+ break;
+ }
+ }
+ }
+ delete ctrlSubPop;
+ }
+
+ //else if (rv == max + 2) // edit instrument
+ // MusEGlobal::muse->startEditInstrument();
+
+ else if (rv == max + 3) { // add new other controller
+ PopupMenu* ctrlSubPop = new PopupMenu(this, true); // true = enable stay open
+ ctrlSubPop->addAction(new MenuTitleItem(tr("Common Controls"), ctrlSubPop));
+
+ for(int num = 0; num < 127; ++num)
+ if(cll->find(channel, num) == cll->end())
+ ctrlSubPop->addAction(MusECore::midiCtrlName(num, true))->setData(num);
+ QAction *act2 = ctrlSubPop->exec(ctrl->mapToGlobal(QPoint(0,0)));
+ if (act2) {
+ int rv2 = act2->data().toInt();
+ int num = rv2;
+ if (isDrum && ((num & 0xff) == 0xff) && curDrumPitch!=-1)
+ num = (num & ~0xff) + MusEGlobal::drumMap[curDrumPitch].anote;
+ if (isNewDrum && ((num & 0xff) == 0xff) && curDrumPitch!=-1)
+ num = (num & ~0xff) + curDrumPitch; //FINDMICHJETZT does this work?
+
+ if(cll->find(channel, num) == cll->end())
+ {
+ MusECore::MidiCtrlValList* vl = new MusECore::MidiCtrlValList(num);
+
+ cll->add(channel, vl);
+ newCtlNum = rv2;
+ }
+ else
+ newCtlNum = rv2;
+ }
+ delete ctrlSubPop;
+ }
+ else { // Select a control
+ MusECore::iMidiCtrlValList i = cll->begin();
+ for (; i != cll->end(); ++i) {
+ MusECore::MidiCtrlValList* cl = i->second;
+ MusECore::MidiController* c = port->midiController(cl->num());
+ if (c->num() == rv) {
+ newCtlNum = c->num();
+ break;
+ }
+ }
+ if (i == cll->end()) {
+ printf("DrumEdit: controller number %d not found!", rv);
+ }
+ }
+
+ if(newCtlNum != -1)
+ {
+ CtrlEdit* ctrlEdit = new CtrlEdit(split1, this, xscale, true, "drumCtrlEdit");
+ ctrlEdit->setController(newCtlNum);
+ setupNewCtrl(ctrlEdit);
+ }
+}
+
+//---------------------------------------------------------
+// addCtrlClicked
+//---------------------------------------------------------
+
+void DrumEdit::addCtrlClicked()
+{
+ PopupMenu* pup = new PopupMenu(true); // true = enable stay open. Don't bother with parent.
+ connect(pup, SIGNAL(triggered(QAction*)), SLOT(ctrlPopupTriggered(QAction*)));
+
+ int est_width = populateMidiCtrlMenu(pup, parts(), curCanvasPart(), curDrumInstrument());
+
+ QPoint ep = ctrl->mapToGlobal(QPoint(0,0));
+ //int newx = ep.x() - pup->width(); // Too much! Width says 640. Maybe because it hasn't been shown yet .
+ int newx = ep.x() - est_width;
+ if(newx < 0)
+ newx = 0;
+ ep.setX(newx);
+ pup->exec(ep);
+ delete pup;
+
+ ctrl->setDown(false);
+}
+
+//---------------------------------------------------------
// addCtrl
//---------------------------------------------------------
-CtrlEdit* DrumEdit::addCtrl()
+CtrlEdit* DrumEdit::addCtrl(int ctl_num)
{
CtrlEdit* ctrlEdit = new CtrlEdit(split1, this, xscale, true, "drumCtrlEdit");
+ ctrlEdit->setController(ctl_num);
+ setupNewCtrl(ctrlEdit);
+ return ctrlEdit;
+ }
+
+//---------------------------------------------------------
+// setupNewCtrl
+//---------------------------------------------------------
+
+void DrumEdit::setupNewCtrl(CtrlEdit* ctrlEdit)
+{
connect(hscroll, SIGNAL(scrollChanged(int)), ctrlEdit, SLOT(setXPos(int)));
connect(hscroll, SIGNAL(scaleChanged(int)), ctrlEdit, SLOT(setXMag(int)));
connect(ctrlEdit, SIGNAL(timeChanged(unsigned)), SLOT(setTime(unsigned)));
@@ -1255,9 +1446,8 @@ CtrlEdit* DrumEdit::addCtrl()
ctrlEdit->show();
ctrlEditList.push_back(ctrlEdit);
- return ctrlEdit;
- }
-
+}
+
//---------------------------------------------------------
// removeCtrl
//---------------------------------------------------------