diff options
49 files changed, 1338 insertions, 317 deletions
diff --git a/muse2/muse/app.cpp b/muse2/muse/app.cpp index 677743b3..386cf226 100644 --- a/muse2/muse/app.cpp +++ b/muse2/muse/app.cpp @@ -1794,6 +1794,7 @@ void MusE::startEditor(MusECore::Track* t)        switch (t->type()) {              case MusECore::Track::MIDI: startPianoroll(); break;                case MusECore::Track::DRUM: startDrumEditor(); break; +            case MusECore::Track::NEW_DRUM: startDrumEditor(); break;              case MusECore::Track::WAVE: startWaveEditor(); break;              default:                    break; diff --git a/muse2/muse/appearance.cpp b/muse2/muse/appearance.cpp index 178c6bd8..6c3ee2e4 100644 --- a/muse2/muse/appearance.cpp +++ b/muse2/muse/appearance.cpp @@ -1,5 +1,4 @@  //========================================================= -//=========================================================  //  MusE  //  Linux Music Editor  //  $Id: appearance.cpp,v 1.11.2.5 2009/11/14 03:37:48 terminator356 Exp $ @@ -843,7 +842,7 @@ void Appearance::colorItemSelectionChanged()              case 0x300: color = &config->waveEditBackgroundColor; break;              case 0x411: color = &config->trackBg;       break;              case 0x412: color = &config->midiTrackBg;   break; -            case 0x413: color = &config->drumTrackBg;   break; +            case 0x413: color = &config->drumTrackBg;   break; //FINDMICHJETZT add newDrum...              case 0x414: color = &config->waveTrackBg;   break;              case 0x415: color = &config->outputTrackBg; break;              case 0x416: color = &config->inputTrackBg;  break; @@ -857,7 +856,7 @@ void Appearance::colorItemSelectionChanged()              case 0x500: color = &config->mixerBg;   break;              case 0x501: color = &config->midiTrackLabelBg;   break; -            case 0x502: color = &config->drumTrackLabelBg;   break; +            case 0x502: color = &config->drumTrackLabelBg;   break; //FINDMICHJETZT add newDrum...              case 0x503: color = &config->waveTrackLabelBg;   break;              case 0x504: color = &config->outputTrackLabelBg; break;              case 0x505: color = &config->inputTrackLabelBg;  break; diff --git a/muse2/muse/arranger/arrangerview.cpp b/muse2/muse/arranger/arrangerview.cpp index 9dc287ac..a565da13 100644 --- a/muse2/muse/arranger/arrangerview.cpp +++ b/muse2/muse/arranger/arrangerview.cpp @@ -634,11 +634,12 @@ void ArrangerView::populateAddTrack()        trackMidiAction = grp->actions()[0];        trackDrumAction = grp->actions()[1]; -      trackWaveAction = grp->actions()[2]; -      trackAOutputAction = grp->actions()[3]; -      trackAGroupAction = grp->actions()[4]; -      trackAInputAction = grp->actions()[5]; -      trackAAuxAction = grp->actions()[6]; +      trackNewStyleDrumAction = grp->actions()[2]; +      trackWaveAction = grp->actions()[3]; +      trackAOutputAction = grp->actions()[4]; +      trackAGroupAction = grp->actions()[5]; +      trackAInputAction = grp->actions()[6]; +      trackAAuxAction = grp->actions()[7];  }  void ArrangerView::addNewTrack(QAction* action) @@ -662,6 +663,7 @@ void ArrangerView::updateShortcuts()        trackMidiAction->setShortcut(shortcuts[SHRT_ADD_MIDI_TRACK].key);        trackDrumAction->setShortcut(shortcuts[SHRT_ADD_DRUM_TRACK].key); +      trackNewStyleDrumAction->setShortcut(shortcuts[SHRT_ADD_NEW_STYLE_DRUM_TRACK].key);        trackWaveAction->setShortcut(shortcuts[SHRT_ADD_WAVE_TRACK].key);        trackAOutputAction->setShortcut(shortcuts[SHRT_ADD_AUDIO_OUTPUT].key);        trackAGroupAction->setShortcut(shortcuts[SHRT_ADD_AUDIO_GROUP].key); diff --git a/muse2/muse/arranger/arrangerview.h b/muse2/muse/arranger/arrangerview.h index de610bd6..d52c5cc4 100644 --- a/muse2/muse/arranger/arrangerview.h +++ b/muse2/muse/arranger/arrangerview.h @@ -89,7 +89,7 @@ class ArrangerView : public TopWin  		QMenu* master;  		QAction *strGlobalCutAction, *strGlobalInsertAction, *strGlobalSplitAction; -		QAction *trackMidiAction, *trackDrumAction, *trackWaveAction, *trackAOutputAction, *trackAGroupAction; +		QAction *trackMidiAction, *trackDrumAction, *trackNewStyleDrumAction, *trackWaveAction, *trackAOutputAction, *trackAGroupAction;  		QAction *trackAInputAction, *trackAAuxAction;  		QAction *editCutAction, *editCopyAction, *editCopyRangeAction;  		QAction *editPasteAction, *editPasteCloneAction, *editPasteDialogAction, *editPasteCloneDialogAction; diff --git a/muse2/muse/arranger/pcanvas.cpp b/muse2/muse/arranger/pcanvas.cpp index 0f2f4629..8226c440 100644 --- a/muse2/muse/arranger/pcanvas.cpp +++ b/muse2/muse/arranger/pcanvas.cpp @@ -238,6 +238,7 @@ void PartCanvas::viewMouseDoubleClickEvent(QMouseEvent* event)                    switch(track->type()) {                          case MusECore::Track::MIDI:                          case MusECore::Track::DRUM: +                        case MusECore::Track::NEW_DRUM:                                {                                MusECore::MidiPart* part = new MusECore::MidiPart((MusECore::MidiTrack*)track);                                part->setTick(pos[1]); @@ -521,6 +522,7 @@ CItem* PartCanvas::newItem(const QPoint& pos, int)        switch(track->type()) {              case MusECore::Track::MIDI:              case MusECore::Track::DRUM: +            case MusECore::Track::NEW_DRUM:                    pa = new MusECore::MidiPart((MusECore::MidiTrack*)track);                    pa->setTick(x);                    pa->setLenTick(0); @@ -659,6 +661,7 @@ QMenu* PartCanvas::genItemPopup(CItem* item)                    act_mexport->setData(16);                    }                    break; +            case MusECore::Track::NEW_DRUM:              case MusECore::Track::DRUM: {                    partPopup->addAction(MusEGlobal::muse->arranger()->parentWin->startDrumEditAction);                    partPopup->addAction(MusEGlobal::muse->arranger()->parentWin->startListEditAction); @@ -1259,6 +1262,7 @@ void PartCanvas::keyPress(QKeyEvent* event)              //  else track is midi              switch (track->type()) { +                  case MusECore::Track::NEW_DRUM:                    case MusECore::Track::DRUM:                          type = 3;                          break; @@ -2302,7 +2306,7 @@ void PartCanvas::drawMidiPart(QPainter& p, const QRect&, MusECore::EventList* ev        using std::pair;        MusECore::iEvent ito(events->lower_bound(to)); -      bool isdrum = (mt->type() == MusECore::Track::DRUM); +      bool isdrum = (mt->type() == MusECore::Track::DRUM  ||  mt->type() == MusECore::Track::NEW_DRUM);        // draw controllers ------------------------------------------        p.setPen(QColor(192,192,color_brightness/2)); diff --git a/muse2/muse/arranger/tlist.cpp b/muse2/muse/arranger/tlist.cpp index 98c4a595..be33808e 100644 --- a/muse2/muse/arranger/tlist.cpp +++ b/muse2/muse/arranger/tlist.cpp @@ -226,6 +226,9 @@ void TList::paint(const QRect& r)                          case MusECore::Track::DRUM:                                bg = MusEGlobal::config.drumTrackBg;                                break; +                        case MusECore::Track::NEW_DRUM: +                              bg = MusEGlobal::config.newDrumTrackBg; +                              break;                          case MusECore::Track::WAVE:                                bg = MusEGlobal::config.waveTrackBg;                                break; @@ -281,6 +284,7 @@ void TList::paint(const QRect& r)                                      case MusECore::Track::MIDI:                                            pm = addtrack_addmiditrackIcon;                                            break; +                                    case MusECore::Track::NEW_DRUM:                                      case MusECore::Track::DRUM:                                            pm = addtrack_drumtrackIcon;                                            break; @@ -585,6 +589,7 @@ void TList::portsPopupMenu(MusECore::Track* t, int x, int y)        switch(t->type()) {              case MusECore::Track::MIDI:              case MusECore::Track::DRUM: +            case MusECore::Track::NEW_DRUM:              case MusECore::Track::AUDIO_SOFTSYNTH:                     {                    MusECore::MidiTrack* track = (MusECore::MidiTrack*)t; @@ -739,7 +744,7 @@ void TList::oportPropertyPopupMenu(MusECore::Track* t, int x, int y)        } -      if (t->type() != MusECore::Track::MIDI && t->type() != MusECore::Track::DRUM) +      if (t->type() != MusECore::Track::MIDI && t->type() != MusECore::Track::DRUM && t->type() != MusECore::Track::NEW_DRUM)              return;        int oPort      = ((MusECore::MidiTrack*)t)->outPort();        MusECore::MidiPort* port = &MusEGlobal::midiPorts[oPort]; @@ -923,7 +928,7 @@ MusECore::TrackList TList::getRecEnabledTracks()  void TList::changeAutomation(QAction* act)  {    //printf("changeAutomation %d\n", act->data().toInt()); -  if (editAutomation->type() == MusECore::Track::MIDI) { +  if ( (editAutomation->type() == MusECore::Track::MIDI) || (editAutomation->type() == MusECore::Track::DRUM) || (editAutomation->type() == MusECore::Track::NEW_DRUM) ) {      printf("this is wrong, we can't edit automation for midi tracks from arranger yet!\n");      return;    } @@ -949,7 +954,7 @@ void TList::changeAutomation(QAction* act)  //---------------------------------------------------------  void TList::changeAutomationColor(QAction* act)  { -  if (editAutomation->type() == MusECore::Track::MIDI) { +  if ( (editAutomation->type() == MusECore::Track::MIDI) || (editAutomation->type() == MusECore::Track::DRUM) || (editAutomation->type() == MusECore::Track::NEW_DRUM) ) {      printf("this is wrong, we can't edit automation for midi tracks from arranger yet!\n");      return;    } @@ -1707,13 +1712,14 @@ void TList::classesPopupMenu(MusECore::Track* t, int x, int y)        p.clear();        p.addAction(QIcon(*addtrack_addmiditrackIcon), tr("Midi"))->setData(MusECore::Track::MIDI);        p.addAction(QIcon(*addtrack_drumtrackIcon), tr("Drum"))->setData(MusECore::Track::DRUM); +      p.addAction(QIcon(*addtrack_drumtrackIcon), tr("New style drum"))->setData(MusECore::Track::NEW_DRUM);        QAction* act = p.exec(mapToGlobal(QPoint(x, y)), 0);        if (!act)              return;        int n = act->data().toInt(); -      if (MusECore::Track::TrackType(n) == MusECore::Track::MIDI && t->type() == MusECore::Track::DRUM) { +      if ((MusECore::Track::TrackType(n) == MusECore::Track::MIDI  ||  MusECore::Track::TrackType(n) == MusECore::Track::NEW_DRUM) && t->type() == MusECore::Track::DRUM) { //FINDMICHJETZT passt das?              //              //    Drum -> Midi              // @@ -1747,11 +1753,11 @@ void TList::classesPopupMenu(MusECore::Track* t, int x, int y)                        }                    } -            t->setType(MusECore::Track::MIDI); +            t->setType(MusECore::Track::TrackType(n));              MusEGlobal::audio->msgIdle(false);              MusEGlobal::song->update(SC_EVENT_MODIFIED);              } -      else if (MusECore::Track::TrackType(n) == MusECore::Track::DRUM && t->type() == MusECore::Track::MIDI) { +      else if (MusECore::Track::TrackType(n) == MusECore::Track::DRUM && (t->type() == MusECore::Track::MIDI  ||  t->type() == MusECore::Track::NEW_DRUM)) { //FINDMICHJETZT passt das?              //              //    Midi -> Drum              // @@ -1809,6 +1815,12 @@ void TList::classesPopupMenu(MusECore::Track* t, int x, int y)              MusEGlobal::audio->msgIdle(false);              MusEGlobal::song->update(SC_EVENT_MODIFIED);              } +      else // MIDI -> NEW_DRUM or vice versa. added by flo. FINDMICHJETZT does this work properly? +      { +            MusECore::Track* t2 = t->clone(false); +            t->setType(MusECore::Track::TrackType(n)); +            MusEGlobal::audio->msgChangeTrack(t2, t, true); +            }        }  } // namespace MusEGui diff --git a/muse2/muse/conf.cpp b/muse2/muse/conf.cpp index c4df1f36..027ad431 100644 --- a/muse2/muse/conf.cpp +++ b/muse2/muse/conf.cpp @@ -788,6 +788,8 @@ void readConfiguration(Xml& xml, bool readOnlySequencer, bool doReadGlobalConfig                                MusEGlobal::config.midiTrackLabelBg = readColor(xml);                          else if (tag == "drumTrackLabelBg")                                MusEGlobal::config.drumTrackLabelBg = readColor(xml); +                        else if (tag == "newDrumTrackLabelBg") +                              MusEGlobal::config.newDrumTrackLabelBg = readColor(xml);                          else if (tag == "waveTrackLabelBg")                                MusEGlobal::config.waveTrackLabelBg = readColor(xml);                          else if (tag == "outputTrackLabelBg") @@ -807,6 +809,8 @@ void readConfiguration(Xml& xml, bool readOnlySequencer, bool doReadGlobalConfig                                MusEGlobal::config.ctrlGraphFg = readColor(xml);                          else if (tag == "drumTrackBg")                                MusEGlobal::config.drumTrackBg = readColor(xml); +                        else if (tag == "newDrumTrackBg") +                              MusEGlobal::config.newDrumTrackBg = readColor(xml);                          else if (tag == "waveTrackBg")                                MusEGlobal::config.waveTrackBg = readColor(xml);                          else if (tag == "outputTrackBg") @@ -1322,6 +1326,7 @@ void MusE::writeGlobalConfiguration(int level, MusECore::Xml& xml) const        xml.colorTag(level, "mixerBg",            MusEGlobal::config.mixerBg);        xml.colorTag(level, "midiTrackLabelBg",   MusEGlobal::config.midiTrackLabelBg);        xml.colorTag(level, "drumTrackLabelBg",   MusEGlobal::config.drumTrackLabelBg); +      xml.colorTag(level, "newDrumTrackLabelBg",MusEGlobal::config.newDrumTrackLabelBg);        xml.colorTag(level, "waveTrackLabelBg",   MusEGlobal::config.waveTrackLabelBg);        xml.colorTag(level, "outputTrackLabelBg", MusEGlobal::config.outputTrackLabelBg);        xml.colorTag(level, "inputTrackLabelBg",  MusEGlobal::config.inputTrackLabelBg); @@ -1332,6 +1337,7 @@ void MusE::writeGlobalConfiguration(int level, MusECore::Xml& xml) const        xml.colorTag(level, "midiTrackBg",   MusEGlobal::config.midiTrackBg);        xml.colorTag(level, "ctrlGraphFg",   MusEGlobal::config.ctrlGraphFg);        xml.colorTag(level, "drumTrackBg",   MusEGlobal::config.drumTrackBg); +      xml.colorTag(level, "newDrumTrackBg",MusEGlobal::config.newDrumTrackBg);        xml.colorTag(level, "waveTrackBg",   MusEGlobal::config.waveTrackBg);        xml.colorTag(level, "outputTrackBg", MusEGlobal::config.outputTrackBg);        xml.colorTag(level, "inputTrackBg",  MusEGlobal::config.inputTrackBg); @@ -1658,6 +1664,7 @@ void MixerConfig::write(int level, MusECore::Xml& xml)        xml.intTag(level, "showMidiTracks",   showMidiTracks);        xml.intTag(level, "showDrumTracks",   showDrumTracks); +      xml.intTag(level, "showNewDrumTracks",   showNewDrumTracks);        xml.intTag(level, "showInputTracks",  showInputTracks);        xml.intTag(level, "showOutputTracks", showOutputTracks);        xml.intTag(level, "showWaveTracks",   showWaveTracks); @@ -1695,6 +1702,8 @@ void MixerConfig::read(MusECore::Xml& xml)                                showMidiTracks = xml.parseInt();                          else if (tag == "showDrumTracks")                                showDrumTracks = xml.parseInt(); +                        else if (tag == "showNewDrumTracks") +                              showNewDrumTracks = xml.parseInt();                          else if (tag == "showInputTracks")                                showInputTracks = xml.parseInt();                          else if (tag == "showOutputTracks") diff --git a/muse2/muse/ctrl/ctrlcanvas.cpp b/muse2/muse/ctrl/ctrlcanvas.cpp index 486e279a..9c5d636f 100644 --- a/muse2/muse/ctrl/ctrlcanvas.cpp +++ b/muse2/muse/ctrl/ctrlcanvas.cpp @@ -537,10 +537,10 @@ void CtrlCanvas::partControllers(const MusECore::MidiPart* part, int num, int* d      int di;      int n; -    if((mt->type() != MusECore::Track::DRUM) && curDrumInstrument != -1) +    if((mt->type() != MusECore::Track::DRUM) && curDrumInstrument != -1) //FINDMICHJETZT was ist das?        printf("keyfilter != -1 in non drum track?\n"); -    if((mt->type() == MusECore::Track::DRUM) && (curDrumInstrument != -1) && ((num & 0xff) == 0xff))  +    if((mt->type() == MusECore::Track::DRUM) && (curDrumInstrument != -1) && ((num & 0xff) == 0xff))  //FINDMICHJETZT was ist das?      {        di = (num & ~0xff) | curDrumInstrument;        n = (num & ~0xff) | MusEGlobal::drumMap[curDrumInstrument].anote;  // construct real controller number @@ -1690,7 +1690,7 @@ void CtrlCanvas::pdrawItems(QPainter& p, const QRect& rect, const MusECore::Midi      MusECore::MidiTrack* mt = part->track();      MusECore::MidiPort* mp; -    if((mt->type() == MusECore::Track::DRUM) && (curDrumInstrument != -1) && ((_cnum & 0xff) == 0xff))  +    if((mt->type() == MusECore::Track::DRUM) && (curDrumInstrument != -1) && ((_cnum & 0xff) == 0xff))  //FINDMICHJETZT was ist das?        mp = &MusEGlobal::midiPorts[MusEGlobal::drumMap[curDrumInstrument].port];                else        mp = &MusEGlobal::midiPorts[mt->outPort()];           diff --git a/muse2/muse/ctrl/ctrlpanel.cpp b/muse2/muse/ctrl/ctrlpanel.cpp index 0d981fbd..88787c47 100644 --- a/muse2/muse/ctrl/ctrlpanel.cpp +++ b/muse2/muse/ctrl/ctrlpanel.cpp @@ -171,7 +171,7 @@ void CtrlPanel::heartBeat()        int outport;        int chan;        int cdi = editor->curDrumInstrument(); -      if(_track->type() == MusECore::Track::DRUM && ((_ctrl->num() & 0xff) == 0xff) && cdi != -1) +      if(_track->type() == MusECore::Track::DRUM && ((_ctrl->num() & 0xff) == 0xff) && cdi != -1) //FINDMICHJETZT was ist das? und ähnliche dinger        {          outport = MusEGlobal::drumMap[cdi].port;          chan = MusEGlobal::drumMap[cdi].channel; @@ -562,7 +562,7 @@ void CtrlPanel::ctrlPopup()        int channel      = track->outChannel();        MusECore::MidiPort* port   = &MusEGlobal::midiPorts[track->outPort()];        int curDrumInstrument = editor->curDrumInstrument(); -      bool isDrum      = track->type() == MusECore::Track::DRUM; +      bool isDrum      = track->type() == MusECore::Track::DRUM; //FINDMICHJETZT ist das wichtig?        QMenu* pop = new QMenu;        //pop->clear(); @@ -720,7 +720,7 @@ void CtrlPanel::ctrlPopup()        int channel      = track->outChannel();        MusECore::MidiPort* port   = &MusEGlobal::midiPorts[track->outPort()];        int curDrumInstrument = editor->curDrumInstrument(); -      bool isDrum      = track->type() == MusECore::Track::DRUM; +      bool isDrum      = track->type() == MusECore::Track::DRUM; //FINDMICHJETZT ist das wichtig?        MusECore::MidiInstrument* instr = port->instrument();        MusECore::MidiControllerList* mcl = instr->controller(); diff --git a/muse2/muse/gconfig.cpp b/muse2/muse/gconfig.cpp index 337d7862..65397fe4 100644 --- a/muse2/muse/gconfig.cpp +++ b/muse2/muse/gconfig.cpp @@ -103,6 +103,7 @@ MusEGui::GlobalConfigValues config = {        QColor(74, 150, 194),         // midiTrackLabelBg;   // Med blue        QColor(74, 150, 194),         // drumTrackLabelBg;   // Med blue +      QColor(74, 150, 194),         // newDrumTrackLabelBg;   // Med blue        QColor(213, 128, 202),        // waveTrackLabelBg;   // magenta        QColor(84, 185, 58),          // outputTrackLabelBg; // green        QColor(199, 75, 64),          // inputTrackLabelBg;  // red @@ -112,6 +113,7 @@ MusEGui::GlobalConfigValues config = {        QColor(215, 220, 230),     // midiTrackBg;        QColor(215, 220, 230),     // drumTrackBg; +      QColor(215, 220, 230),     // newDrumTrackBg;        QColor(220, 209, 217),     // waveTrackBg;        QColor(197, 220, 206),     // outputTrackBg;        QColor(220, 214, 206),     // inputTrackBg; @@ -149,13 +151,13 @@ MusEGui::GlobalConfigValues config = {           QString("Mixer A"),           QRect(0, 0, 300, 500),        // Mixer1           true, true, true, true, -         true, true, true, true +         true, true, true, true, true           },        {           QString("Mixer B"),           QRect(200, 200, 300, 500),    // Mixer2           true, true, true, true, -         true, true, true, true +         true, true, true, true, true           },        true,                         // TransportVisible;        false,                        // BigTimeVisible; diff --git a/muse2/muse/gconfig.h b/muse2/muse/gconfig.h index df6739cf..a6b55557 100644 --- a/muse2/muse/gconfig.h +++ b/muse2/muse/gconfig.h @@ -47,6 +47,7 @@ struct MixerConfig {        QRect geometry;        bool showMidiTracks;        bool showDrumTracks; +      bool showNewDrumTracks;        bool showInputTracks;        bool showOutputTracks;        bool showWaveTracks; @@ -83,6 +84,7 @@ struct GlobalConfigValues {        QColor midiTrackLabelBg;        QColor drumTrackLabelBg; +      QColor newDrumTrackLabelBg;        QColor waveTrackLabelBg;        QColor outputTrackLabelBg;        QColor inputTrackLabelBg; @@ -92,6 +94,7 @@ struct GlobalConfigValues {        QColor midiTrackBg;        QColor drumTrackBg; +      QColor newDrumTrackBg;        QColor waveTrackBg;        QColor outputTrackBg;        QColor inputTrackBg; diff --git a/muse2/muse/helper.cpp b/muse2/muse/helper.cpp index a3a4639c..e3cdee7e 100644 --- a/muse2/muse/helper.cpp +++ b/muse2/muse/helper.cpp @@ -98,6 +98,19 @@ bool any_event_selected(const set<Part*>& parts, bool in_range)    return !get_events(parts, in_range ? 3 : 1).empty();  } +bool drummaps_almost_equal(DrumMap* one, DrumMap* two, int len) +{ +  for (int i=0; i<len; i++) +  { +    DrumMap tmp = one[i]; +    tmp.mute=two[i].mute; +    if (tmp!=two[i]) +      return false; +  } +  return true; +} + +  } // namespace MusECore  namespace MusEGui { @@ -293,26 +306,44 @@ QActionGroup* populateAddTrack(QMenu* addTrack)                                            QT_TRANSLATE_NOOP("@default", "Add Midi Track"));        midi->setData(MusECore::Track::MIDI);        grp->addAction(midi); + +        QAction* drum = addTrack->addAction(QIcon(*addtrack_drumtrackIcon),                                            QT_TRANSLATE_NOOP("@default", "Add Drum Track"));        drum->setData(MusECore::Track::DRUM);        grp->addAction(drum); + + +      QAction* newdrum = addTrack->addAction(QIcon(*addtrack_drumtrackIcon), +                                          QT_TRANSLATE_NOOP("@default", "Add New Style Drum Track")); +      newdrum->setData(MusECore::Track::NEW_DRUM); +      grp->addAction(newdrum); + +        QAction* wave = addTrack->addAction(QIcon(*addtrack_wavetrackIcon),                                            QT_TRANSLATE_NOOP("@default", "Add Wave Track"));        wave->setData(MusECore::Track::WAVE);        grp->addAction(wave); + +        QAction* aoutput = addTrack->addAction(QIcon(*addtrack_audiooutputIcon),                                               QT_TRANSLATE_NOOP("@default", "Add Audio Output"));        aoutput->setData(MusECore::Track::AUDIO_OUTPUT);        grp->addAction(aoutput); + +        QAction* agroup = addTrack->addAction(QIcon(*addtrack_audiogroupIcon),                                              QT_TRANSLATE_NOOP("@default", "Add Audio Group"));        agroup->setData(MusECore::Track::AUDIO_GROUP);        grp->addAction(agroup); + +        QAction* ainput = addTrack->addAction(QIcon(*addtrack_audioinputIcon),                                              QT_TRANSLATE_NOOP("@default", "Add Audio Input"));        ainput->setData(MusECore::Track::AUDIO_INPUT);        grp->addAction(ainput); + +        QAction* aaux = addTrack->addAction(QIcon(*addtrack_auxsendIcon),                                            QT_TRANSLATE_NOOP("@default", "Add Aux Send"));        aaux->setData(MusECore::Track::AUDIO_AUX); diff --git a/muse2/muse/helper.h b/muse2/muse/helper.h index a2361ab5..f014ee1e 100644 --- a/muse2/muse/helper.h +++ b/muse2/muse/helper.h @@ -25,6 +25,8 @@  #include <set> +#include "drummap.h" +  class QActionGroup;  class QString;  class QMenu; @@ -36,6 +38,8 @@ class Part;  QString pitch2string(int v);  Part* partFromSerialNumber(int serial);  bool any_event_selected(const std::set<Part*>&, bool in_range=false); + +bool drummaps_almost_equal(DrumMap* one, DrumMap* two, int drummap_size=128);  }  namespace MusEGui { diff --git a/muse2/muse/icons.cpp b/muse2/muse/icons.cpp index 6991eab8..67bb4827 100644 --- a/muse2/muse/icons.cpp +++ b/muse2/muse/icons.cpp @@ -120,6 +120,10 @@  #include "xpm/rec_echo_on.xpm"  #include "xpm/rec_echo_off.xpm" +#include "xpm/eye.xpm" +#include "xpm/eye_gray.xpm" +#include "xpm/eye_crossed.xpm" +  #include "xpm/up.xpm"  #include "xpm/down.xpm"  #include "xpm/bold.xpm" @@ -333,6 +337,9 @@ QPixmap* homeIcon;  QPixmap* backIcon;  QPixmap* forwardIcon;  QPixmap* muteIcon; +QPixmap* eyeIcon; +QPixmap* eyeCrossedIcon; +QPixmap* eyeGrayIcon;  QPixmap* upIcon;  QPixmap* downIcon;  QPixmap* boldIcon; @@ -536,6 +543,9 @@ void initIcons()        backIcon     = new MPIXMAP(back_xpm, "go-previous");        forwardIcon  = new MPIXMAP(forward_xpm, "go-next");        muteIcon     = new MPIXMAP(editmuteS_xpm, "audio-volume-muted"); +      eyeIcon      = new MPIXMAP(eye_xpm, NULL); +      eyeCrossedIcon  = new MPIXMAP(eye_crossed_xpm, NULL); +      eyeGrayIcon  = new MPIXMAP(eye_gray_xpm, NULL);        upIcon       = new MPIXMAP(up_xpm, "go-up");        downIcon     = new MPIXMAP(down_xpm, "go-down");        boldIcon     = new MPIXMAP(bold_xpm, "format-text-bold"); diff --git a/muse2/muse/icons.h b/muse2/muse/icons.h index 0c576ba4..32f08a58 100644 --- a/muse2/muse/icons.h +++ b/muse2/muse/icons.h @@ -87,6 +87,9 @@ extern QPixmap* homeIcon;  extern QPixmap* backIcon;  extern QPixmap* forwardIcon;  extern QPixmap* muteIcon; +extern QPixmap* eyeIcon; +extern QPixmap* eyeCrossedIcon; +extern QPixmap* eyeGrayIcon;  extern QPixmap* upIcon;  extern QPixmap* downIcon;  extern QPixmap* boldIcon; diff --git a/muse2/muse/importmidi.cpp b/muse2/muse/importmidi.cpp index e94a4ea8..593ddb79 100644 --- a/muse2/muse/importmidi.cpp +++ b/muse2/muse/importmidi.cpp @@ -181,7 +181,7 @@ bool MusE::importMidi(const QString name, bool merge)                          MusECore::MidiTrack* track = new MusECore::MidiTrack();                          if ((*t)->isDrumTrack) -                              track->setType(MusECore::Track::DRUM); +                              track->setType(MusECore::Track::DRUM); //FINDMICHJETZT                          track->setOutChannel(channel);                          track->setOutPort(port); @@ -200,7 +200,7 @@ bool MusE::importMidi(const QString name, bool merge)                          // Hmm. buildMidiEventList already takes care of this.                           // But it seems to work. How? Must test.                           if (channel == 9 && MusEGlobal::song->mtype() != MT_UNKNOWN) { -                              track->setType(MusECore::Track::DRUM); +                              track->setType(MusECore::Track::DRUM); //FINDMICHJETZT                                //                                // remap drum pitch with drumInmap                                // diff --git a/muse2/muse/liste/editevent.cpp b/muse2/muse/liste/editevent.cpp index bca5729b..ce53069d 100644 --- a/muse2/muse/liste/editevent.cpp +++ b/muse2/muse/liste/editevent.cpp @@ -619,7 +619,7 @@ EditCtrlDialog::EditCtrlDialog(int tick, const MusECore::Event& event,        MusECore::MidiTrack* track   = part->track();        int portn          = track->outPort();        MusECore::MidiPort* port     = &MusEGlobal::midiPorts[portn]; -      bool isDrum        = track->type() == MusECore::Track::DRUM; +      bool isDrum        = track->type() == MusECore::Track::DRUM; //FINDMICHJETZT was soll das?        MusECore::MidiCtrlValListList* cll = port->controller();        ctrlList->clear(); @@ -835,7 +835,7 @@ void EditCtrlDialog::updatePatch()        int port              = track->outPort();        int channel           = track->outChannel();        MusECore::MidiInstrument* instr = MusEGlobal::midiPorts[port].instrument(); -      patchName->setText(instr->getPatchName(channel, val, MusEGlobal::song->mtype(), track->type() == MusECore::Track::DRUM)); +      patchName->setText(instr->getPatchName(channel, val, MusEGlobal::song->mtype(), track->type() == MusECore::Track::DRUM));  //FINDMICHJETZT was soll das?        int hb = ((val >> 16) & 0xff) + 1;        if (hb == 0x100) @@ -874,7 +874,7 @@ void EditCtrlDialog::instrPopup()        ///instr->populatePatchPopup(pop, channel, MusEGlobal::song->mtype(), track->type() == MusECore::Track::DRUM);        //QMenu* pup = new QMenu(this);        MusEGui::PopupMenu* pup = new MusEGui::PopupMenu(this); -      populatePatchPopup(instr, pup, channel, MusEGlobal::song->mtype(), track->type() == MusECore::Track::DRUM); +      populatePatchPopup(instr, pup, channel, MusEGlobal::song->mtype(), track->type() == MusECore::Track::DRUM);  //FINDMICHJETZT was soll das?        ///if(pop->actions().count() == 0)        ///  return; diff --git a/muse2/muse/midi.cpp b/muse2/muse/midi.cpp index 0d81ff2c..e927674f 100644 --- a/muse2/muse/midi.cpp +++ b/muse2/muse/midi.cpp @@ -257,7 +257,7 @@ void buildMidiEventList(EventList* del, const MPEventList* el, MidiTrack* track,                    case ME_NOTEON:                          e.setType(Note); -                        if (track->type() == Track::DRUM) { +                        if (track->type() == Track::DRUM) { //FINDMICHJETZT                                int instr = MusEGlobal::drumInmap[ev.dataA()];                                e.setPitch(instr);                                } @@ -271,7 +271,7 @@ void buildMidiEventList(EventList* del, const MPEventList* el, MidiTrack* track,                          break;                    case ME_NOTEOFF:                          e.setType(Note); -                        if (track->type() == Track::DRUM) { +                        if (track->type() == Track::DRUM) { //FINDMICHJETZT                                int instr = MusEGlobal::drumInmap[ev.dataA()];                                e.setPitch(instr);                                } @@ -373,7 +373,7 @@ void buildMidiEventList(EventList* del, const MPEventList* el, MidiTrack* track,                                      int ctl = ev.dataA();                                      e.setA(ctl); -                                    if(track->type() == Track::DRUM)  +                                    if(track->type() == Track::DRUM)  //FINDMICHJETZT drum controller?                                      {                                        // Is it a drum controller event, according to the track port's instrument?                                        MidiController *mc = MusEGlobal::midiPorts[track->outPort()].drumController(ctl); @@ -730,7 +730,7 @@ void Audio::collectEvents(MusECore::MidiTrack* track, unsigned int cts, unsigned                    //                    if (ev.type() == Meta)                          continue; -                  if (track->type() == Track::DRUM) { +                  if (track->type() == Track::DRUM) { //FINDMICHJETZT ignore muted                          int instr = ev.pitch();                          // ignore muted drums                          if (ev.isNote() && MusEGlobal::drumMap[instr].mute) @@ -754,7 +754,7 @@ void Audio::collectEvents(MusECore::MidiTrack* track, unsigned int cts, unsigned                                     channel   = MusEGlobal::drumMap[instr].channel;                                     velo      = int(double(velo) * (double(MusEGlobal::drumMap[instr].vol) / 100.0)) ;                                     } -                              else { +                              else { //FINDMICHJETZT don't transpose for new style drum tracks                                      //                                      // transpose non drum notes                                      // @@ -807,7 +807,7 @@ void Audio::collectEvents(MusECore::MidiTrack* track, unsigned int cts, unsigned                          case Controller:                                { -                                if (track->type() == Track::DRUM)   +                                if (track->type() == Track::DRUM)   //FINDMICHJETZT was ist das? drumcontroller -_-                                  {                                    int ctl   = ev.dataA();                                    // Is it a drum controller event, according to the track port's instrument? @@ -979,7 +979,7 @@ void Audio::processMidi()                                        //                                        //Apply drum inkey: -                                      if (track->type() == Track::DRUM)  +                                      if (track->type() == Track::DRUM)  //FINDMICHJETZT schwierig...                                        {                                              int pitch = event.dataA();                                              //Map note that is played according to MusEGlobal::drumInmap @@ -1016,7 +1016,7 @@ void Audio::processMidi()                                  else                                  if(event.type() == MusECore::ME_CONTROLLER)                                  { -                                  if(track->type() == Track::DRUM)  +                                  if(track->type() == Track::DRUM)  //FINDMICHJETZT was ist das?                                    {                                      ctl = event.dataA();                                      // Regardless of what port the event came from, is it a drum controller event  @@ -1079,7 +1079,7 @@ void Audio::processMidi()                                        //  to the track port so buildMidiEventList will accept it. Even though                                         //  the port may have no device "<none>".                                        // -                                      if (track->type() == Track::DRUM)  +                                      if (track->type() == Track::DRUM)  //FINDMICHJETZT was ist das?                                        {                                          // Is it a drum controller event?                                          if(mc) diff --git a/muse2/muse/midiedit/dcanvas.cpp b/muse2/muse/midiedit/dcanvas.cpp index da94986b..22db70d0 100644 --- a/muse2/muse/midiedit/dcanvas.cpp +++ b/muse2/muse/midiedit/dcanvas.cpp @@ -34,12 +34,12 @@  #include <stdio.h>  #include <values.h>  #include <errno.h> -#include <set>  //#include <sys/stat.h>  //#include <sys/mman.h>  #include "dcanvas.h"  #include "midieditor.h" +#include "drumedit.h"  #include "drummap.h"  #include "event.h"  #include "mpevent.h" @@ -50,20 +50,23 @@  #include "shortcuts.h"  #include "icons.h"  #include "functions.h" +#include "helper.h"  #define CARET   10  #define CARET2   5 +using MusEGlobal::debugMsg; +using MusEGlobal::heavyDebugMsg; +  namespace MusEGui {  //---------------------------------------------------------  //   DEvent  //--------------------------------------------------------- -DEvent::DEvent(MusECore::Event e, MusECore::Part* p) +DEvent::DEvent(MusECore::Event e, MusECore::Part* p, int instr)    : CItem(e, p)        { -      int instr = e.pitch();        int y  = instr * TH + TH/2;        int tick = e.tick() + p->tick();        setPos(QPoint(tick, y)); @@ -81,7 +84,14 @@ void DrumCanvas::addItem(MusECore::Part* part, MusECore::Event& event)              return;        } -      DEvent* ev = new DEvent(event, part); +      int instr=pitch_and_track_to_instrument(event.pitch(), part->track()); +      if (instr<0) +      { +        if (heavyDebugMsg) printf("trying to add event which is hidden or not in any part known to me\n"); +        return; +      } +       +      DEvent* ev = new DEvent(event, part, instr);        items.add(ev);        int diff = event.endTick()-part->lenTick(); @@ -103,6 +113,35 @@ DrumCanvas::DrumCanvas(MidiEditor* pr, QWidget* parent, int sx,     int sy, const char* name)     : EventCanvas(pr, parent, sx, sy, name)        { +      drumEditor=dynamic_cast<DrumEdit*>(pr); +       +      old_style_drummap_mode = drumEditor->old_style_drummap_mode(); + +      if (old_style_drummap_mode) +      { +        if (debugMsg) printf("DrumCanvas in old style drummap mode\n"); +        ourDrumMap = MusEGlobal::drumMap; +        must_delete_our_drum_map=false; +         +        instrument_number_mapping_t temp; +        for (MusECore::ciPart it=drumEditor->parts()->begin(); it!=drumEditor->parts()->end(); it++) +          temp.tracks.insert(it->second->track()); + +        for (int i=0;i<DRUM_MAPSIZE;i++) +        { +          temp.pitch=i; +          instrument_map.append(temp); +        } +      } +      else +      { +        if (debugMsg) printf("DrumCanvas in new style drummap mode\n"); +        ourDrumMap=NULL; +        rebuildOurDrumMap(); +      } +       +       +              setVirt(false);        cursorPos= QPoint(0,0);        _stepSize=1; @@ -116,6 +155,10 @@ DrumCanvas::DrumCanvas(MidiEditor* pr, QWidget* parent, int sx,  DrumCanvas::~DrumCanvas()  {    //items.clearDelete(); +   +  if (must_delete_our_drum_map && ourDrumMap!=NULL) +    delete [] ourDrumMap; +    delete steprec;  }  //--------------------------------------------------------- @@ -195,7 +238,7 @@ MusECore::Undo DrumCanvas::moveCanvasItems(CItemList& items, int dp, int dx, Dra  		for(iCItem ici = items.begin(); ici != items.end(); ++ici)   		{ -		        CItem* ci = ici->second; +			CItem* ci = ici->second;  			int x = ci->pos().x();  			int y = ci->pos().y(); @@ -217,7 +260,7 @@ MusECore::Undo DrumCanvas::moveCanvasItems(CItemList& items, int dp, int dx, Dra  				doneList.push_back(ci);  			}  			ci->move(newpos); -						 +        			if(moving.size() == 1)   						itemReleased(curItem, newpos); @@ -258,10 +301,20 @@ MusECore::UndoOp DrumCanvas::moveItem(CItem* item, const QPoint& pos, DragType d        int ntick        = editor->rasterVal(x) - part->tick();        if (ntick < 0)              ntick = 0; -      int npitch       = y2pitch(pos.y()); +      int nheight       = y2pitch(pos.y());        MusECore::Event newEvent   = event.clone(); - -      newEvent.setPitch(npitch); +       +      MusECore::Track* dest_track = part->track(); +      if (!instrument_map[nheight].tracks.contains(dest_track)) +      { +        printf ("TODO FIXME: tried to move an event into a different track. this is not supported yet, but will be soon. ignoring this one...\n"); +        //FINDMICH +        return MusECore::UndoOp(); +      } +       +      int ev_pitch = instrument_map[nheight].pitch; +       +      newEvent.setPitch(ev_pitch);        newEvent.setTick(ntick);        // Added by T356, removed by flo93: with operation groups, it happens that the @@ -282,13 +335,13 @@ MusECore::UndoOp DrumCanvas::moveItem(CItem* item, const QPoint& pos, DragType d  CItem* DrumCanvas::newItem(const QPoint& p, int state)        {        int instr = y2pitch(p.y());         //MusEGlobal::drumInmap[y2pitch(p.y())]; -      int velo  = MusEGlobal::drumMap[instr].lv4; +      int velo  = ourDrumMap[instr].lv4;        if (state == Qt::ShiftModifier) -            velo = MusEGlobal::drumMap[instr].lv3; +            velo = ourDrumMap[instr].lv3;        else if (state == Qt::ControlModifier) -            velo = MusEGlobal::drumMap[instr].lv2; +            velo = ourDrumMap[instr].lv2;        else if (state == (Qt::ControlModifier | Qt::ShiftModifier)) -            velo = MusEGlobal::drumMap[instr].lv1; +            velo = ourDrumMap[instr].lv1;        int tick = editor->rasterVal(p.x());        return newItem(tick, instr, velo);        } @@ -299,13 +352,22 @@ CItem* DrumCanvas::newItem(const QPoint& p, int state)  CItem* DrumCanvas::newItem(int tick, int instrument, int velocity)  { -  tick    -= curPart->tick(); -  MusECore::Event e(MusECore::Note); -  e.setTick(tick); -  e.setPitch(instrument); -  e.setVelo(velocity); -  e.setLenTick(MusEGlobal::drumMap[instrument].len); -  return new DEvent(e, curPart); +  if (!old_style_drummap_mode && !instrument_map[instrument].tracks.contains(curPart->track())) +  { +    printf("FINDMICH: tried to create a new Item which cannot be inside the current track. returning NULL\n"); +    return NULL; +  } +  else +  { +    tick    -= curPart->tick(); +    MusECore::Event e(MusECore::Note); +    e.setTick(tick); +    e.setPitch(instrument_map[instrument].pitch); +    e.setVelo(velocity); +    e.setLenTick(ourDrumMap[instrument].len); + +    return new DEvent(e, curPart, instrument); +  }  }  //--------------------------------------------------------- @@ -328,7 +390,9 @@ void DrumCanvas::newItem(CItem* item, bool noSnap) {  }  void DrumCanvas::newItem(CItem* item, bool noSnap, bool replace) -      { +{ +   if (item) +   {        DEvent* nevent = (DEvent*) item;        MusECore::Event event    = nevent->event();        int x = item->x(); @@ -336,7 +400,7 @@ void DrumCanvas::newItem(CItem* item, bool noSnap, bool replace)              x = editor->rasterVal(x);        event.setTick(x - nevent->part()->tick());        int npitch = event.pitch(); -      event.setPitch(npitch); +      //event.setPitch(npitch); // commented out by flo: has no effect        //        // check for existing event @@ -372,7 +436,7 @@ void DrumCanvas::newItem(CItem* item, bool noSnap, bool replace)        {          operations.push_back(MusECore::UndoOp(MusECore::UndoOp::AddEvent,event, part, false, false)); -        if (diff > 0)// part must be extended? +        if (diff > 0) // part must be extended?          {                schedule_resize_all_same_len_clone_parts(part, event.endTick(), operations);                printf("newItem: extending\n"); @@ -382,7 +446,10 @@ void DrumCanvas::newItem(CItem* item, bool noSnap, bool replace)        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"); +}  //---------------------------------------------------------  //   deleteItem @@ -437,7 +504,7 @@ void DrumCanvas::drawItem(QPainter&p, const CItem*item, const QRect& rect)        else        {              int velo    = e->event().velo(); -            MusECore::DrumMap* dm = &MusEGlobal::drumMap[y2pitch(y)]; //Get the drum item +            MusECore::DrumMap* dm = &ourDrumMap[y2pitch(y)]; //Get the drum item              QColor color;              if (velo < dm->lv1)                    color.setRgb(240, 240, 255); @@ -528,8 +595,8 @@ void DrumCanvas::drawTopItem(QPainter& p, const QRect&)  int DrumCanvas::y2pitch(int y) const        {        int pitch = y/TH; -      if (pitch >= DRUM_MAPSIZE) -            pitch = DRUM_MAPSIZE-1; +      if (pitch >= instrument_map.size()) +            pitch = instrument_map.size()-1;        return pitch;        } @@ -638,7 +705,8 @@ void DrumCanvas::cmd(int cmd)                                DEvent* devent = (DEvent*)(k->second);                                MusECore::Event event    = devent->event();                                MusECore::Event newEvent = event.clone(); -                              newEvent.setLenTick(MusEGlobal::drumMap[event.pitch()].len); +                              // newEvent.setLenTick(drumMap[event.pitch()].len); +                              newEvent.setLenTick(ourDrumMap[y2pitch(devent->y())].len);                                // Indicate no undo, and do not do port controller values and clone parts.                                 MusEGlobal::audio->msgChangeEvent(event, newEvent, devent->part(), false, false, false);                                } @@ -740,19 +808,19 @@ void DrumCanvas::dragLeaveEvent(QDragLeaveEvent*)  //   keyPressed - called from DList  //--------------------------------------------------------- -void DrumCanvas::keyPressed(int index, int velocity) +void DrumCanvas::keyPressed(int index, int velocity) //FINDMICH later        {        // called from DList - play event -      int port = MusEGlobal::drumMap[index].port; -      int channel = MusEGlobal::drumMap[index].channel; -      int pitch = MusEGlobal::drumMap[index].anote; +      int port = ourDrumMap[index].port; +      int channel = ourDrumMap[index].channel; +      int pitch = ourDrumMap[index].anote;        // play note:        MusECore::MidiPlayEvent e(0, port, channel, 0x90, pitch, velocity);        MusEGlobal::audio->msgPlayMidiEvent(&e);        if (_steprec && pos[0] >= start_tick /* && pos[0] < end_tick [removed by flo93: this is handled in steprec->record] */ && curPart) -            steprec->record(curPart,index,MusEGlobal::drumMap[index].len,editor->raster(),velocity,MusEGlobal::globalKeyState&Qt::ControlModifier,MusEGlobal::globalKeyState&Qt::ShiftModifier); +            steprec->record(curPart,index,ourDrumMap[index].len,editor->raster(),velocity,MusEGlobal::globalKeyState&Qt::ControlModifier,MusEGlobal::globalKeyState&Qt::ShiftModifier);        } @@ -760,12 +828,12 @@ void DrumCanvas::keyPressed(int index, int velocity)  //   keyReleased  //--------------------------------------------------------- -void DrumCanvas::keyReleased(int index, bool) +void DrumCanvas::keyReleased(int index, bool) //FINDMICH later        {        // called from DList - silence playing event -      int port = MusEGlobal::drumMap[index].port; -      int channel = MusEGlobal::drumMap[index].channel; -      int pitch = MusEGlobal::drumMap[index].anote; +      int port = ourDrumMap[index].port; +      int channel = ourDrumMap[index].channel; +      int pitch = ourDrumMap[index].anote;        // release note:        MusECore::MidiPlayEvent e(0, port, channel, 0x90, pitch, 0); @@ -777,7 +845,12 @@ void DrumCanvas::keyReleased(int index, bool)  //---------------------------------------------------------  void DrumCanvas::mapChanged(int spitch, int dpitch) -      { +{ +   // spitch may be the same as dpitch! and something in here must be executed +   // even if they're same (i assume it's song->update(SC_DRUMMAP)) (flo93) +    +   if (old_style_drummap_mode) +   {        MusECore::Undo operations;        std::vector< std::pair<MusECore::Part*, MusECore::Event*> > delete_events;        std::vector< std::pair<MusECore::Part*, MusECore::Event> > add_events; @@ -855,7 +928,74 @@ void DrumCanvas::mapChanged(int spitch, int dpitch)        MusEGlobal::song->applyOperationGroup(operations, false); // do not indicate undo        MusEGlobal::song->update(SC_DRUMMAP); //this update is neccessary, as it's not handled by applyOperationGroup() +   } +   else // if (!old_style_drummap_mode) +   { +      if (dpitch!=spitch) +      { +        using MusEGlobal::global_drum_ordering_t; +        using MusEGlobal::global_drum_ordering; +         +        MusECore::DrumMap dm_temp = ourDrumMap[spitch]; +        instrument_number_mapping_t im_temp = instrument_map[spitch]; + +        global_drum_ordering_t order_temp; +        for (global_drum_ordering_t::iterator it=global_drum_ordering.begin(); it!=global_drum_ordering.end();) +        { +          if (im_temp.pitch==it->second && im_temp.tracks.contains(it->first)) +          { +            order_temp.push_back(*it); +            it=global_drum_ordering.erase(it); +          } +          else +            it++; +        } +         +        // the instrument represented by instrument_map[dpitch] is always the instrument +        // which will be immediately AFTER our dragged instrument +        for (global_drum_ordering_t::iterator it=global_drum_ordering.begin(); it!=global_drum_ordering.end(); it++) +          if (instrument_map[dpitch].pitch==it->second && instrument_map[dpitch].tracks.contains(it->first)) +          { +            while (!order_temp.empty()) +              it=global_drum_ordering.insert(it, order_temp.takeLast()); + +            break; +          } + + + + + +        if (dpitch > spitch) +        { +          for (int i=spitch; i<dpitch-1; i++) +          { +            ourDrumMap[i]=ourDrumMap[i+1]; +            instrument_map[i]=instrument_map[i+1]; +          } +           +          ourDrumMap[dpitch-1] = dm_temp; +          instrument_map[dpitch-1] = im_temp; +        } +        else if (spitch > dpitch) +        { +          for (int i=spitch; i>dpitch; i--) +          { +            ourDrumMap[i]=ourDrumMap[i-1]; +            instrument_map[i]=instrument_map[i-1]; +          } +           +          ourDrumMap[dpitch] = dm_temp; +          instrument_map[dpitch] = im_temp; +        }        } +       +       +      MusEGlobal::song->update(SC_DRUMMAP); // this causes a complete rebuild of ourDrumMap +                                            // which also handles the changed order in all +                                            // other drum editors +   } +}  //---------------------------------------------------------  //   resizeEvent @@ -907,6 +1047,7 @@ void DrumCanvas::modifySelected(NoteInfo::ValType type, int delta)                          printf("DrumCanvas::modifySelected - NoteInfo::VAL_VELOFF not implemented\n");                          break;                    case NoteInfo::VAL_PITCH: +                        if (old_style_drummap_mode)                          {                          int pitch = event.pitch() - delta; // Reversing order since the drumlist is displayed in increasing order                          if (pitch > 127) @@ -915,6 +1056,8 @@ void DrumCanvas::modifySelected(NoteInfo::ValType type, int delta)                                pitch = 0;                          newEvent.setPitch(pitch);                          } +                        else +                          printf("DrumCanvas::modifySelected - MusEWidget::NoteInfo::VAL_PITCH not implemented for new style drum editors\n");                          break;                    }              MusEGlobal::song->changeEvent(event, newEvent, part); @@ -992,8 +1135,8 @@ void DrumCanvas::keyPress(QKeyEvent* event)        return;      }      else if (key == shortcuts[SHRT_ADDNOTE_1].key) { -          newItem(newItem(cursorPos.x(), cursorPos.y(), MusEGlobal::drumMap[cursorPos.y()].lv1),false,true); -          keyPressed(cursorPos.y(), MusEGlobal::drumMap[cursorPos.y()].lv1); +          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()); @@ -1002,8 +1145,8 @@ void DrumCanvas::keyPress(QKeyEvent* event)            return;      }      else if (key == shortcuts[SHRT_ADDNOTE_2].key) { -          newItem(newItem(cursorPos.x(), cursorPos.y(), MusEGlobal::drumMap[cursorPos.y()].lv2),false,true); -          keyPressed(cursorPos.y(), MusEGlobal::drumMap[cursorPos.y()].lv2); +          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()); @@ -1012,8 +1155,8 @@ void DrumCanvas::keyPress(QKeyEvent* event)            return;      }      else if (key == shortcuts[SHRT_ADDNOTE_3].key) { -          newItem(newItem(cursorPos.x(), cursorPos.y(), MusEGlobal::drumMap[cursorPos.y()].lv3),false,true); -          keyPressed(cursorPos.y(), MusEGlobal::drumMap[cursorPos.y()].lv3); +          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()); @@ -1022,8 +1165,8 @@ void DrumCanvas::keyPress(QKeyEvent* event)            return;      }      else if (key == shortcuts[SHRT_ADDNOTE_4].key) { -          newItem(newItem(cursorPos.x(), cursorPos.y(), MusEGlobal::drumMap[cursorPos.y()].lv4),false,true); -          keyPressed(cursorPos.y(), MusEGlobal::drumMap[cursorPos.y()].lv4); +          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()); @@ -1071,17 +1214,19 @@ MusECore::Event *DrumCanvas::getEventAtCursorPos()  {      if (_tool != CursorTool)        return 0; -    MusECore::EventList* el = curPart->events(); -    MusECore::iEvent lower  = el->lower_bound(cursorPos.x()-curPart->tick()); -    MusECore::iEvent upper  = el->upper_bound(cursorPos.x()-curPart->tick()); -    for (MusECore::iEvent i = lower; i != upper; ++i) { -      MusECore::Event &ev = i->second; -      if(!ev.isNote()) -        continue; -      if (ev.pitch() == cursorPos.y()) { -        return &ev; +    if (instrument_map[cursorPos.y()].tracks.contains(curPart->track())) +    { +      MusECore::EventList* el = curPart->events(); +      MusECore::iEvent lower  = el->lower_bound(cursorPos.x()-curPart->tick()); +      MusECore::iEvent upper  = el->upper_bound(cursorPos.x()-curPart->tick()); +      int curPitch = instrument_map[cursorPos.y()].pitch; +      for (MusECore::iEvent i = lower; i != upper; ++i) { +        MusECore::Event &ev = i->second; +        if (ev.isNote()  &&  ev.pitch() == curPitch) +          return &ev;        }      } +    // else or if the for loop didn't find anything      return 0;  }  //--------------------------------------------------------- @@ -1105,9 +1250,13 @@ void DrumCanvas::selectCursorEvent(MusECore::Event *ev)  void DrumCanvas::moveAwayUnused()  { -	using std::set; +  if (!old_style_drummap_mode) +  { +    printf("THIS SHOULD NEVER HAPPEN: DrumCanvas::moveAwayUnused() cannot be used in new style mode\n"); +    return; +  } -	set<int> used; +	QSet<int> used;  	for (iCItem it=items.begin(); it!=items.end(); it++)  	{  		const MusECore::Event& ev=it->second->event(); @@ -1117,7 +1266,7 @@ void DrumCanvas::moveAwayUnused()  	}  	int count=0; -	for (set<int>::iterator it=used.begin(); it!=used.end();) +	for (QSet<int>::iterator it=used.begin(); it!=used.end();)  	{  		while ((*it != count) && (used.find(count)!=used.end())) count++; @@ -1134,16 +1283,200 @@ void DrumCanvas::moveAwayUnused()  //---------------------------------------------------------  //   midiNote  //--------------------------------------------------------- -void DrumCanvas::midiNote(int pitch, int velo) +void DrumCanvas::midiNote(int pitch, int velo) //FINDMICH later.        { -      if (MusEGlobal::debugMsg) printf("DrumCanvas::midiNote: pitch=%i, velo=%i\n", pitch, velo); +      if (debugMsg) printf("DrumCanvas::midiNote: pitch=%i, velo=%i\n", pitch, velo);        if (_midiin && _steprec && curPart           && !MusEGlobal::audio->isPlaying() && velo && pos[0] >= start_tick -         /* && pos[0] < end_tick [removed by flo93: this is handled in steprec->record] */ +         /* && pos[0] < end_tick [removed by flo93: this is handled in steprec->record()] */           && !(MusEGlobal::globalKeyState & Qt::AltModifier)) { -                                               steprec->record(curPart,MusEGlobal::drumInmap[pitch],MusEGlobal::drumMap[(int)MusEGlobal::drumInmap[pitch]].len,editor->raster(),velo,MusEGlobal::globalKeyState&Qt::ControlModifier,MusEGlobal::globalKeyState&Qt::ShiftModifier); +            steprec->record(curPart,MusEGlobal::drumInmap[pitch],ourDrumMap[(int)MusEGlobal::drumInmap[pitch]].len,editor->raster(),velo,MusEGlobal::globalKeyState&Qt::ControlModifier,MusEGlobal::globalKeyState&Qt::ShiftModifier);           }        } + +int DrumCanvas::pitch_and_track_to_instrument(int pitch, MusECore::Track* track) +{ +  for (int i=0; i<instrument_map.size(); i++) +    if (instrument_map[i].tracks.contains(track) && instrument_map[i].pitch==pitch) +      return i; +   +  printf("ERROR: DrumCanvas::pitch_and_track_to_instrument() called with invalid arguments!\n"); +  return -1; +} + +void DrumCanvas::propagate_drummap_change(int instr) +{ +  const QSet<MusECore::Track*>& tracks=instrument_map[instr].tracks; +  int index=instrument_map[instr].pitch; +   +  for (QSet<MusECore::Track*>::const_iterator it = tracks.begin(); it != tracks.end(); it++) +    dynamic_cast<MusECore::MidiTrack*>(*it)->drummap()[index] = ourDrumMap[instr]; +} + + +void DrumCanvas::rebuildOurDrumMap() +{ +  using MusECore::drummaps_almost_equal; +  using MusECore::Track; +  using MusECore::MidiTrack; +  using MusECore::TrackList; +  using MusECore::ciTrack; +  using MusECore::ciPart; +  using MusECore::DrumMap; +  using MusEGlobal::global_drum_ordering_t; +  using MusEGlobal::global_drum_ordering; +   +   +  if (!old_style_drummap_mode) +  { +    bool need_update = false; +     +    TrackList* tl=MusEGlobal::song->tracks(); +    QList< QSet<Track*> > track_groups; +    QVector<instrument_number_mapping_t> old_instrument_map = instrument_map; +     +    instrument_map.clear(); + +    for (ciTrack track = tl->begin(); track!=tl->end(); track++) +    { +      ciPart p_it; +      for (p_it=drumEditor->parts()->begin(); p_it!=drumEditor->parts()->end(); p_it++) +        if (p_it->second->track() == *track) +          break; +       +      if (p_it!=drumEditor->parts()->end()) // if *track is represented by some part in this editor +      { +        bool inserted=false; +         +        switch (drumEditor->group_mode()) +        { +          case DrumEdit::GROUP_SAME_CHANNEL: +            for (QList< QSet<Track*> >::iterator group=track_groups.begin(); group!=track_groups.end(); group++) +              if ( ((MidiTrack*)*group->begin())->outChannel() == ((MidiTrack*)*track)->outChannel()  && +                   ((MidiTrack*)*group->begin())->outPort() == ((MidiTrack*)*track)->outPort()  && +                   (drummaps_almost_equal(((MidiTrack*)*group->begin())->drummap(), ((MidiTrack*)*track)->drummap())) ) +              { +                group->insert(*track); +                inserted=true; +                break; +              } +            break; +           +          case DrumEdit::GROUP_MAX: +            for (QList< QSet<Track*> >::iterator group=track_groups.begin(); group!=track_groups.end(); group++) +              if (drummaps_almost_equal(((MidiTrack*)*group->begin())->drummap(), ((MidiTrack*)*track)->drummap())) +              { +                group->insert(*track); +                inserted=true; +                break; +              } +            break; +           +          case DrumEdit::DONT_GROUP:  +            inserted=false; +            break; +           +          default: +            printf("THIS SHOULD NEVER HAPPEN: group_mode() is invalid!\n"); +            inserted=false; +        } + +        if (!inserted) +        { +          QSet<Track*> temp; +          temp.insert(*track); +          track_groups.push_back(temp); +        } +      } +    } + +    // from now, we assume that every track_group's entry only groups tracks with identical +    // drum maps, but not necessarily identical hide-lists together. +    QList< std::pair<MidiTrack*,int> > ignore_order_entries; +    for (global_drum_ordering_t::iterator order_it=global_drum_ordering.begin(); order_it!=global_drum_ordering.end(); order_it++) +    { +      // if this entry should be ignored, ignore it. +      if (ignore_order_entries.contains(*order_it)) +        continue; +       +      // look if we have order_it->first (the MidiTrack*) in any of our track groups +      QList< QSet<Track*> >::iterator group; +      for (group=track_groups.begin(); group!=track_groups.end(); group++) +        if (group->contains(order_it->first)) +          break; +       +      if (group!=track_groups.end()) // we have +      { +        int pitch=order_it->second; +         +        bool mute=true; +        bool hidden=true; +         +        if (drumEditor->ignore_hide()) hidden=false; +         +        for (QSet<Track*>::iterator track=group->begin(); track!=group->end() && (mute || hidden); track++) +        { +          if (dynamic_cast<MidiTrack*>(*track)->drummap()[pitch].mute == false) +            mute=false; +           +          if (dynamic_cast<MidiTrack*>(*track)->drummap_hidden()[pitch] == false) +            hidden=false; +        } + +        if (!hidden) +        { +          for (QSet<Track*>::iterator track=group->begin(); track!=group->end(); track++) +          { +            DrumMap* dm = &dynamic_cast<MidiTrack*>(*track)->drummap()[pitch]; +            if (dm->mute != mute) +            { +              dm->mute=mute;  +              need_update = true; +            } +          } +           +          if (dynamic_cast<MidiTrack*>(*group->begin())->drummap()[pitch].anote != pitch) +            printf("THIS SHOULD NEVER HAPPEN: track's_drummap[pitch].anote (%i)!= pitch (%i) !!!\n",dynamic_cast<MidiTrack*>(*group->begin())->drummap()[pitch].anote,pitch); +           +          instrument_map.append(instrument_number_mapping_t(*group, pitch)); +        } +         +        for (QSet<Track*>::iterator track=group->begin(); track!=group->end(); track++) +          ignore_order_entries.append(std::pair<MidiTrack*,int>(dynamic_cast<MidiTrack*>(*track), pitch)); +      } +      // else ignore it +    } + + +    // maybe delete and then populate ourDrumMap +     +    if (must_delete_our_drum_map && ourDrumMap!=NULL) +      delete [] ourDrumMap; +     +    int size = instrument_map.size(); +    ourDrumMap=new DrumMap[size]; +    must_delete_our_drum_map=true; + +    for (int i=0;i<size;i++) +      ourDrumMap[i] = dynamic_cast<MidiTrack*>(*instrument_map[i].tracks.begin())->drummap()[instrument_map[i].pitch];   +     +    if (instrument_map!=old_instrument_map) +    { +    if (debugMsg) printf("rebuilt drummap and instrument map, size is now %i\n",size); +     +      songChanged(SC_EVENT_INSERTED); // force an update of the itemlist +      emit ourDrumMapChanged(true); +    } +    else +      emit ourDrumMapChanged(false); +     +    if (need_update) +      MusEGlobal::song->update(SC_DRUMMAP, true); // i know, this causes a recursion, which possibly +                                                  // isn't the most elegant solution here. but it will +                                                  // never be an infinite recursion +  } +} +  } // namespace MusEGui diff --git a/muse2/muse/midiedit/dcanvas.h b/muse2/muse/midiedit/dcanvas.h index bc9dbdbc..581de9d7 100644 --- a/muse2/muse/midiedit/dcanvas.h +++ b/muse2/muse/midiedit/dcanvas.h @@ -26,6 +26,9 @@  #include "ecanvas.h"  #include "song.h"  #include "steprec.h" +#include <map> +#include <QList> +#include <QSet>  #define TH 18 @@ -36,11 +39,11 @@ class QDropEvent;  class QDragMoveEvent;  class QDragLeaveEvent; +class DrumMap;  namespace MusEGui {  class MidiEditor; -class PianoRoll; -class ScrollScale; +class DrumEdit;  //---------------------------------------------------------  //   DEvent @@ -49,9 +52,38 @@ class ScrollScale;  class DEvent : public CItem {     public: -      DEvent(MusECore::Event e, MusECore::Part* p); +      DEvent(MusECore::Event e, MusECore::Part* p, int instr);        }; + +struct instrument_number_mapping_t //FINDMICH TODO move into a suitable namespace! +{ +  QSet<MusECore::Track*> tracks; +  int pitch; +   +  instrument_number_mapping_t() +  { +    pitch=-1; +    tracks.clear(); +  } +   +  instrument_number_mapping_t(const QSet<MusECore::Track*>& tr, int p) +  { +    tracks=tr; +    pitch=p; +  } +   +  bool operator==(const instrument_number_mapping_t& that) //TODO maybe compare the Track* serial numbers, not the pointers themselves? +  { +    return (this->tracks == that.tracks && this->pitch==that.pitch); +  } +   +  bool operator!=(const instrument_number_mapping_t& that) +  { +    return !operator==(that); +  } +}; +  //---------------------------------------------------------  //   DrumCanvas  //--------------------------------------------------------- @@ -59,6 +91,13 @@ class DEvent : public CItem {  class DrumCanvas : public EventCanvas {        Q_OBJECT +      bool old_style_drummap_mode; +      MusECore::DrumMap* ourDrumMap; +      bool must_delete_our_drum_map; //FINDMICH really delete it! +      QVector<instrument_number_mapping_t> instrument_map; +       +      DrumEdit* drumEditor; +              MusECore::StepRec* steprec;        // Cursor tool position @@ -89,9 +128,10 @@ class DrumCanvas : public EventCanvas {        virtual void resizeEvent(QResizeEvent*);        virtual void curPartChanged();        int getNextStep(unsigned int pos, int basicStep, int stepSize=1); - +           signals:        void newWidth(int); +      void ourDrumMapChanged(bool /*instrumentMap changed as well?*/);     private slots:        void midiNote(int pitch, int velo); @@ -111,7 +151,8 @@ class DrumCanvas : public EventCanvas {           CMD_SELECT_ALL, CMD_SELECT_NONE, CMD_SELECT_INVERT,           CMD_SELECT_ILOOP, CMD_SELECT_OLOOP, CMD_SELECT_PREV_PART, CMD_SELECT_NEXT_PART,            CMD_DEL, CMD_FIXED_LEN, CMD_RIGHT, CMD_LEFT, CMD_RIGHT_NOSNAP, CMD_LEFT_NOSNAP, CMD_MODIFY_VELOCITY, CMD_CRESCENDO, -         CMD_QUANTIZE, CMD_ERASE_EVENT, CMD_NOTE_SHIFT, CMD_DELETE_OVERLAPS, CMD_REORDER_LIST +         CMD_QUANTIZE, CMD_ERASE_EVENT, CMD_NOTE_SHIFT, CMD_DELETE_OVERLAPS, CMD_REORDER_LIST, +         CMD_GROUP_NONE, CMD_GROUP_CHAN, CMD_GROUP_MAX           };        DrumCanvas(MidiEditor*, QWidget*, int, int,           const char* name = 0); @@ -121,7 +162,12 @@ class DrumCanvas : public EventCanvas {        virtual void keyPress(QKeyEvent* event);        MusECore::Event *getEventAtCursorPos();        void selectCursorEvent(MusECore::Event *ev); - +      int pitch_and_track_to_instrument(int pitch, MusECore::Track* track); +      MusECore::DrumMap* getOurDrumMap() { return ourDrumMap; } //FINDMICH UGLY +      int getOurDrumMapSize() { return instrument_map.size(); } //FINDMICH UGLY +      QVector<instrument_number_mapping_t>& get_instrument_map() { return instrument_map; } //FINDMICH UGLY +      void propagate_drummap_change(int instrument); //FINDMICH move to drumedit +      void rebuildOurDrumMap();        };  } // namespace MusEGui diff --git a/muse2/muse/midiedit/dlist.cpp b/muse2/muse/midiedit/dlist.cpp index 0e1f8986..1ffae02e 100644 --- a/muse2/muse/midiedit/dlist.cpp +++ b/muse2/muse/midiedit/dlist.cpp @@ -33,11 +33,12 @@  #include "pitchedit.h"  #include "midiport.h"  #include "drummap.h" +#include "drumedit.h"  #include "helper.h"  #include "icons.h"  #include "dlist.h"  #include "song.h" -#include "scrollscale.h" +#include "dcanvas.h"  namespace MusEGui { @@ -58,13 +59,13 @@ void DList::draw(QPainter& p, const QRect& rect)        p.setPen(Qt::black); -      for (int i = 0; i < DRUM_MAPSIZE; ++i) { -            int yy = i * TH; +      for (int instrument = 0; instrument < ourDrumMapSize; ++instrument) { +            int yy = instrument * TH;              if (yy+TH < y)                    continue;              if (yy > y + h)                    break; -            MusECore::DrumMap* dm = &MusEGlobal::drumMap[i]; +            MusECore::DrumMap* dm = &ourDrumMap[instrument];              if (dm == currentlySelected)                    p.fillRect(x, yy, w, TH, Qt::yellow);  //            else @@ -73,6 +74,10 @@ void DList::draw(QPainter& p, const QRect& rect)              p.save();              p.setWorldMatrixEnabled(false);              for (int k = 0; k < h->count(); ++k) { +                  if (h->isSectionHidden(k)) +                      continue; +                   +                                      int x   = h->sectionPosition(k);                    int w   = h->sectionSize(k);                    //QRect r = p.combinedTransform().mapRect(QRect(x+2, yy, w-4, TH));  // Gives inconsistent positions. Source shows wrong operation for our needs. @@ -83,33 +88,72 @@ void DList::draw(QPainter& p, const QRect& rect)                    //p.save();                    //p.setWorldMatrixEnabled(false);                    switch (k) { -                        case COL_VOL: +                        case COL_VOLUME:                                s.setNum(dm->vol);                                break; -                        case COL_QNT: +                        case COL_QUANT:                                s.setNum(dm->quant);                                break; -                        case COL_LEN: +                        case COL_NOTELENGTH:                                s.setNum(dm->len);                                break; -                        case COL_ANOTE: +                        case COL_NOTE:                                s =  MusECore::pitch2string(dm->anote);                                break; -                        case COL_ENOTE: +                        case COL_INPUTTRIGGER:                                s =  MusECore::pitch2string(dm->enote);                                break; -                        case COL_LV1: +                        case COL_LEVEL1:                                s.setNum(dm->lv1);                                break; -                        case COL_LV2: +                        case COL_LEVEL2:                                s.setNum(dm->lv2);                                break; -                        case COL_LV3: +                        case COL_LEVEL3:                                s.setNum(dm->lv3);                                break; -                        case COL_LV4: +                        case COL_LEVEL4:                                s.setNum(dm->lv4);                                break; +                        case COL_HIDE: +                        { +                              bool hidden=false; +                              bool shown=false; +                              QSet<MusECore::Track*>* group = &dcanvas->get_instrument_map()[instrument].tracks; +                              int pitch = dcanvas->get_instrument_map()[instrument].pitch; +                               +                              for (QSet<MusECore::Track*>::iterator track=group->begin(); track!=group->end() && !(hidden&&shown); track++) +                                if (dynamic_cast<MusECore::MidiTrack*>(*track)->drummap_hidden()[pitch]) +                                  hidden=true; +                                else +                                  shown=true; +                               +                              if (!hidden && !shown) +                                printf("THIS SHOULD NEVER HAPPEN: in DList::draw(): instrument %i's track group is empty. strange...\n", instrument); +                               +                              const QPixmap* pm = NULL; +                               +                              if (shown && !hidden) +                                    pm = eyeIcon; +                              else if (!shown && hidden) +                                    pm = eyeCrossedIcon; +                              else if (shown && hidden) +                                    pm = eyeGrayIcon; +                              else //if (!shown && !hidden) +                                    pm = NULL; +                               +                              if (pm) +                              { +                               // p.setPen(Qt::red); +                                p.drawPixmap( +                                   r.x() + r.width()/2 - pm->width()/2, +                                   r.y() + r.height()/2 - pm->height()/2, +                                   *pm); +                               // p.setPen(Qt::black); +                              } +                                     +                              break; +                        }                          case COL_MUTE:                                if (dm->mute) {                                      p.setPen(Qt::red); @@ -125,10 +169,10 @@ void DList::draw(QPainter& p, const QRect& rect)                                s = dm->name;                                align = Qt::AlignVCenter | Qt::AlignLeft;                                break; -                        case COL_CHANNEL: +                        case COL_OUTCHANNEL:                                s.setNum(dm->channel+1);                                break; -                        case COL_PORT: +                        case COL_OUTPORT:                                s.sprintf("%d:%s", dm->port+1, MusEGlobal::midiPorts[dm->port].portname().toLatin1().constData());                                align = Qt::AlignVCenter | Qt::AlignLeft;                                break; @@ -180,6 +224,12 @@ void DList::draw(QPainter& p, const QRect& rect)  void DList::devicesPopupMenu(MusECore::DrumMap* t, int x, int y, bool changeAll)        { +      if (!old_style_drummap_mode) +      { +        printf("THIS SHOULD NEVER HAPPEN: devicesPopupMenu() called in new style mode!\n"); +        return; +      } +              QMenu* p = MusECore::midiPortsPopup();        QAction* act = p->exec(mapToGlobal(QPoint(x, y)), 0);        bool doemit = false; @@ -201,8 +251,8 @@ void DList::devicesPopupMenu(MusECore::DrumMap* t, int x, int y, bool changeAll)                    // Delete all port controller events.                    MusEGlobal::song->changeAllPortDrumCtrlEvents(false); -                  for (int i = 0; i < DRUM_MAPSIZE; i++) -                        MusEGlobal::drumMap[i].port = n; +                  for (int i = 0; i < ourDrumMapSize; i++) +                        ourDrumMap[i].port = n;                    // Add all port controller events.                    MusEGlobal::song->changeAllPortDrumCtrlEvents(true); @@ -229,16 +279,17 @@ void DList::viewMousePressEvent(QMouseEvent* ev)        int x      = ev->x();        int y      = ev->y();        int button = ev->button(); -      unsigned pitch = y / TH; -      MusECore::DrumMap* dm = &MusEGlobal::drumMap[pitch]; +      unsigned instrument = y / TH; +      MusECore::DrumMap* dm = &ourDrumMap[instrument]; +      MusECore::DrumMap dm_old = *dm; -      setCurDrumInstrument(pitch); +      setCurDrumInstrument(instrument);        startY = y; -      sPitch = pitch; +      sInstrument = instrument;        drag   = START_DRAG; -      DCols col = DCols(x2col(x)); +      DrumColumn col = DrumColumn(x2col(x));        int val;        int incVal = 0; @@ -252,7 +303,7 @@ void DList::viewMousePressEvent(QMouseEvent* ev)        // In that case, treat it as if a return was pressed        if (button == Qt::LeftButton) { -            if (((editEntry && editEntry != dm)  || col != selectedColumn) && editEntry != 0) { +            if (editEntry && (editEntry != dm  || col != selectedColumn)) {                    returnPressed();                    }              } @@ -260,54 +311,77 @@ void DList::viewMousePressEvent(QMouseEvent* ev)        switch (col) {              case COL_NONE:                    break; +            case COL_HIDE: +                  if (button == Qt::LeftButton) +                  { +                    bool hidden=true; +                    QSet<MusECore::Track*>* group = &dcanvas->get_instrument_map()[instrument].tracks; +                    int pitch = dcanvas->get_instrument_map()[instrument].pitch; +                     +                    for (QSet<MusECore::Track*>::iterator track=group->begin(); track!=group->end(); track++) +                      if (dynamic_cast<MusECore::MidiTrack*>(*track)->drummap_hidden()[pitch] == false) +                      { +                        hidden=false; +                        break; +                      } +                     +                    for (QSet<MusECore::Track*>::iterator track=group->begin(); track!=group->end(); track++) +                      dynamic_cast<MusECore::MidiTrack*>(*track)->drummap_hidden()[pitch] = !hidden; +                  } +                  break;              case COL_MUTE:                    if (button == Qt::LeftButton)                          dm->mute = !dm->mute;                    break; -            case COL_PORT: +            case COL_OUTPORT: // this column isn't visible in new style drum mode                    if ((button == Qt::RightButton) || (button == Qt::LeftButton)) {                          bool changeAll = ev->modifiers() & Qt::ControlModifier; -                        devicesPopupMenu(dm, mapx(x), mapy(pitch * TH), changeAll); +                        devicesPopupMenu(dm, mapx(x), mapy(instrument * TH), changeAll);                          }                    break; -            case COL_VOL: +            case COL_VOLUME:                    val = dm->vol + incVal;                    if (val < 0)                          val = 0; -                  else if (val > 200) -                        val = 200; +                  else if (val > 999) //changed from 200 to 999 by flo93 +                        val = 999;                    dm->vol = (unsigned char)val;                          break; -            case COL_QNT: +            case COL_QUANT:                    dm->quant += incVal;                    // ?? range                    break; -            case COL_ENOTE: +            case COL_INPUTTRIGGER:                    val = dm->enote + incVal;                    if (val < 0)                          val = 0;                    else if (val > 127)                          val = 127; -                  //Check if there is any other MusEGlobal::drumMap with the same inmap value (there should be one (and only one):-) -                  //If so, switch the inmap between the instruments -                  for (int i=0; i<DRUM_MAPSIZE; i++) { -                        if (MusEGlobal::drumMap[i].enote == val && &MusEGlobal::drumMap[i] != dm) { -                              MusEGlobal::drumInmap[int(dm->enote)] = i; -                              MusEGlobal::drumMap[i].enote = dm->enote; -                              break; -                              } -                        } -                  //TODO: Set all the notes on the track with pitch=dm->enote to pitch=val +                   +                  if (old_style_drummap_mode) +                  { +                      //Check if there is any other drumMap with the same inmap value (there should be one (and only one):-) +                      //If so, switch the inmap between the instruments +                      for (int i=0; i<ourDrumMapSize; i++) { +                            if (ourDrumMap[i].enote == val && &ourDrumMap[i] != dm) { +                                  MusEGlobal::drumInmap[int(dm->enote)] = i; +                                  ourDrumMap[i].enote = dm->enote; +                                  break; +                                  } +                            } +                      //TODO: Set all the notes on the track with instrument=dm->enote to instrument=val +                      MusEGlobal::drumInmap[val] = instrument; +                  }                    dm->enote = val; -                  MusEGlobal::drumInmap[val] = pitch;                    break; -            case COL_LEN: +            case COL_NOTELENGTH:                    val = dm->len + incVal;                    if (val < 0)                          val = 0;                    dm->len = val;                    break; -            case COL_ANOTE: +            case COL_NOTE: +                  if (old_style_drummap_mode) //only allow changing in old style mode                    {                      val = dm->anote + incVal;                      if (val < 0) @@ -317,16 +391,19 @@ void DList::viewMousePressEvent(QMouseEvent* ev)                      if(val != dm->anote)                      {                        MusEGlobal::audio->msgIdle(true); -                      MusEGlobal::song->remapPortDrumCtrlEvents(pitch, val, -1, -1); +                      MusEGlobal::song->remapPortDrumCtrlEvents(instrument, val, -1, -1);                        MusEGlobal::audio->msgIdle(false);                        dm->anote = val;                        MusEGlobal::song->update(SC_DRUMMAP);                      } -                    int velocity = 127 * float(ev->x()) / width(); -                    emit keyPressed(pitch, velocity);//(dm->anote, shift); +                  } +                   +                  { +                  int velocity = 127 * float(ev->x()) / width(); +                  emit keyPressed(instrument, velocity);//(dm->anote, shift);                    }                    break; -            case COL_CHANNEL: +            case COL_OUTCHANNEL: // this column isn't visible in new style drum mode                    val = dm->channel + incVal;                    if (val < 0)                          val = 0; @@ -338,8 +415,8 @@ void DList::viewMousePressEvent(QMouseEvent* ev)                          // Delete all port controller events.                          MusEGlobal::song->changeAllPortDrumCtrlEvents(false, true); -                        for (int i = 0; i < DRUM_MAPSIZE; i++) -                              MusEGlobal::drumMap[i].channel = val; +                        for (int i = 0; i < ourDrumMapSize; i++) +                              ourDrumMap[i].channel = val;                          // Add all port controller events.                          MusEGlobal::song->changeAllPortDrumCtrlEvents(true, true);                          MusEGlobal::audio->msgIdle(false); @@ -350,14 +427,14 @@ void DList::viewMousePressEvent(QMouseEvent* ev)                        if(val != dm->channel)                        {                          MusEGlobal::audio->msgIdle(true); -                        MusEGlobal::song->remapPortDrumCtrlEvents(pitch, -1, val, -1); +                        MusEGlobal::song->remapPortDrumCtrlEvents(instrument, -1, val, -1);                          MusEGlobal::audio->msgIdle(false);                          dm->channel = val;                          MusEGlobal::song->update(SC_DRUMMAP);                        }                      }                          break; -            case COL_LV1: +            case COL_LEVEL1:                    val = dm->lv1 + incVal;                    if (val < 0)                          val = 0; @@ -365,7 +442,7 @@ void DList::viewMousePressEvent(QMouseEvent* ev)                          val = 127;                    dm->lv1 = val;                    break; -            case COL_LV2: +            case COL_LEVEL2:                    val = dm->lv2 + incVal;                    if (val < 0)                          val = 0; @@ -373,7 +450,7 @@ void DList::viewMousePressEvent(QMouseEvent* ev)                          val = 127;                    dm->lv2 = val;                    break; -            case COL_LV3: +            case COL_LEVEL3:                    val = dm->lv3 + incVal;                    if (val < 0)                          val = 0; @@ -381,7 +458,7 @@ void DList::viewMousePressEvent(QMouseEvent* ev)                          val = 127;                    dm->lv3 = val;                    break; -            case COL_LV4: +            case COL_LEVEL4:                    val = dm->lv4 + incVal;                    if (val < 0)                          val = 0; @@ -390,13 +467,59 @@ void DList::viewMousePressEvent(QMouseEvent* ev)                    dm->lv4 = val;                    break;              case COL_NAME: -                  emit keyPressed(pitch, 100); //Mapping done on other side, send index +                  if (button == Qt::LeftButton) +                      emit keyPressed(instrument, 100); //Mapping done on other side, send index +                  else if (button == Qt::MidButton) // hide that instrument +                  { +                    QSet<MusECore::Track*>* group = &dcanvas->get_instrument_map()[instrument].tracks; +                    int pitch = dcanvas->get_instrument_map()[instrument].pitch; +                    for (QSet<MusECore::Track*>::iterator track=group->begin(); track!=group->end(); track++) +                      dynamic_cast<MusECore::MidiTrack*>(*track)->drummap_hidden()[pitch] = true;                     +                  } +                  else if (button == Qt::RightButton) +                  { +                    bool hidden=false; +                    bool shown=false; +                    QSet<MusECore::Track*>* group = &dcanvas->get_instrument_map()[instrument].tracks; +                    int pitch = dcanvas->get_instrument_map()[instrument].pitch; +                     +                    for (QSet<MusECore::Track*>::iterator track=group->begin(); track!=group->end() && !(hidden&&shown); track++) +                      if (dynamic_cast<MusECore::MidiTrack*>(*track)->drummap_hidden()[pitch]) +                        hidden=true; +                      else +                        shown=true; + +                    QMenu* popup = new QMenu(NULL /* intendedly not "this" */);  +                    QAction* hideAction = popup->addAction(tr("hide this instrument")); +                    QAction* showAction = popup->addAction(tr("show this instrument")); +                    showAction->setToolTip(tr("this turns a grayed out eye into a blue eye")); +                     +                    if (!hidden) +                      showAction->setEnabled(false); +                    if (!shown) +                      hideAction->setEnabled(false); +                     +                    QAction* result = popup->exec(ev->globalPos()); +                    if (result==hideAction) +                      for (QSet<MusECore::Track*>::iterator track=group->begin(); track!=group->end(); track++) +                        dynamic_cast<MusECore::MidiTrack*>(*track)->drummap_hidden()[pitch] = true;                     +                    else if (result==showAction) +                      for (QSet<MusECore::Track*>::iterator track=group->begin(); track!=group->end(); track++) +                        dynamic_cast<MusECore::MidiTrack*>(*track)->drummap_hidden()[pitch] = false;        +                     +                    delete popup; +                  }                    break;              default:                    break;              } -      redraw(); +       +      if (!old_style_drummap_mode && dm_old != *dm) //something changed and we're in new style mode? +        dcanvas->propagate_drummap_change(dm-ourDrumMap); +       +      MusEGlobal::song->update(SC_DRUMMAP); +      //redraw(); //this is done by the songChanged slot        }  //--------------------------------------------------------- @@ -407,18 +530,18 @@ void DList::viewMouseDoubleClickEvent(QMouseEvent* ev)        {        int x = ev->x();        int y = ev->y(); -      unsigned pitch = y / TH; +      unsigned instrument = y / TH;        int section = header->logicalIndexAt(x); -      if ((section == COL_NAME || section == COL_VOL || section == COL_LEN || section == COL_LV1 || -         section == COL_LV2 || section == COL_LV3 || section == COL_LV4 || section == COL_CHANNEL || -         section == COL_QNT) && (ev->button() == Qt::LeftButton)) +      if ((section == COL_NAME || section == COL_VOLUME || section == COL_NOTELENGTH || section == COL_LEVEL1 || +         section == COL_LEVEL2 || section == COL_LEVEL3 || section == COL_LEVEL4 || section == COL_QUANT || +         (section == COL_OUTCHANNEL && old_style_drummap_mode) ) && (ev->button() == Qt::LeftButton))           { -           lineEdit(pitch, section); +           lineEdit(instrument, section);           } -      else if ((section == COL_ANOTE || section == COL_ENOTE) && (ev->button() == Qt::LeftButton)) -        pitchEdit(pitch, section); +      else if (((section == COL_NOTE && old_style_drummap_mode) || section == COL_INPUTTRIGGER) && (ev->button() == Qt::LeftButton)) +        pitchEdit(instrument, section);        else              viewMousePressEvent(ev);        } @@ -430,7 +553,7 @@ void DList::viewMouseDoubleClickEvent(QMouseEvent* ev)  //---------------------------------------------------------  void DList::lineEdit(int line, int section)        { -            MusECore::DrumMap* dm = &MusEGlobal::drumMap[line]; +            MusECore::DrumMap* dm = &ourDrumMap[line];              editEntry = dm;              if (editor == 0) {                    editor = new DLineEdit(this); @@ -448,37 +571,37 @@ void DList::lineEdit(int line, int section)                    editor->setText(dm->name);                    break; -                  case COL_VOL: { +                  case COL_VOLUME: {                    editor->setText(QString::number(dm->vol));                    break;                    } -                  case COL_LEN: { +                  case COL_NOTELENGTH: {                    editor->setText(QString::number(dm->len));                    break;                    } -                  case COL_LV1: +                  case COL_LEVEL1:                    editor->setText(QString::number(dm->lv1));                    break; -                  case COL_LV2: +                  case COL_LEVEL2:                    editor->setText(QString::number(dm->lv2));                    break; -                  case COL_LV3: +                  case COL_LEVEL3:                    editor->setText(QString::number(dm->lv3));                    break; -                  case COL_LV4: +                  case COL_LEVEL4:                    editor->setText(QString::number(dm->lv4));                    break; -                  case COL_QNT: +                  case COL_QUANT:                    editor->setText(QString::number(dm->quant));                    break; -                  case COL_CHANNEL: +                  case COL_OUTCHANNEL:                    editor->setText(QString::number(dm->channel+1));                    break;              } @@ -498,7 +621,7 @@ void DList::lineEdit(int line, int section)  //---------------------------------------------------------  void DList::pitchEdit(int line, int section)        { -            MusECore::DrumMap* dm = &MusEGlobal::drumMap[line]; +            MusECore::DrumMap* dm = &ourDrumMap[line];              editEntry = dm;              if (pitch_editor == 0) {                    pitch_editor = new DPitchEdit(this); @@ -512,11 +635,11 @@ void DList::pitchEdit(int line, int section)              int colh = rmapy(TH);              selectedColumn = section; //Store selected column to have an idea of which one was selected when return is pressed              switch (section) { -                  case COL_ENOTE: +                  case COL_INPUTTRIGGER:                    pitch_editor->setValue(dm->enote);                    break; -                  case COL_ANOTE: +                  case COL_NOTE:                    pitch_editor->setValue(dm->anote);                    break;              } @@ -552,11 +675,11 @@ int DList::x2col(int x) const  void DList::setCurDrumInstrument(int instr)        { -      if (instr < 0 || instr >= DRUM_MAPSIZE -1) +      if (instr < 0 || instr >= ourDrumMapSize -1)          return; // illegal instrument -      MusECore::DrumMap* dm = &MusEGlobal::drumMap[instr]; +      MusECore::DrumMap* dm = &ourDrumMap[instr];        if (currentlySelected != dm) { -            currentlySelected = &MusEGlobal::drumMap[instr]; +            currentlySelected = dm;              emit curDrumInstrumentChanged(instr);              MusEGlobal::song->update(SC_DRUMMAP);              } @@ -577,32 +700,37 @@ void DList::sizeChange(int, int, int)  void DList::returnPressed()        { +      if (editEntry==NULL) +      { +        printf("THIS SHOULD NEVER HAPPEN: editEntry is NULL in DList::returnPressed()!\n"); +        return; +      } +              int val = -1;        if (selectedColumn != COL_NAME)         { -            ///val = atoi(editor->text().ascii());              val = atoi(editor->text().toAscii().constData());              switch (selectedColumn)              { -              case COL_VOL: -                  if (val > 200) //Check bounds for volume -                  val = 200; +              case COL_VOLUME: +                  if (val > 999) //changed from 200 to 999 by flo93 +                  val = 999;                    if (val < 0)                    val = 0;                    break; -              case COL_LV1: -              case COL_LV2: -              case COL_LV3: -              case COL_LV4: +              case COL_LEVEL1: +              case COL_LEVEL2: +              case COL_LEVEL3: +              case COL_LEVEL4:                    if (val > 127) //Check bounds for lv1-lv4 values                    val = 127;                    if (val < 0)                    val = 0;                    break; -              case COL_CHANNEL: +              case COL_OUTCHANNEL:                    val--;                    if (val >= 16)                    val = 15; @@ -613,42 +741,42 @@ void DList::returnPressed()                default: break;              }          }      - +       +      MusECore::DrumMap editEntryOld = *editEntry;        switch(selectedColumn) {              case COL_NAME:                    editEntry->name = editor->text();                    break; -            case COL_LEN: -                  ///editEntry->len = atoi(editor->text().ascii()); +            case COL_NOTELENGTH:                    editEntry->len = atoi(editor->text().toAscii().constData());                    break; -            case COL_VOL: +            case COL_VOLUME:                    editEntry->vol = val;                    break; -            case COL_LV1: +            case COL_LEVEL1:                    editEntry->lv1 = val;                    break; -            case COL_LV2: +            case COL_LEVEL2:                    editEntry->lv2 = val;                    break; -            case COL_LV3: +            case COL_LEVEL3:                    editEntry->lv3 = val;                    break; -            case COL_LV4: +            case COL_LEVEL4:                    editEntry->lv4 = val;                    break; -            case COL_QNT: +            case COL_QUANT:                    editEntry->quant = val;                    break; -            case COL_CHANNEL: +            case COL_OUTCHANNEL:                    editEntry->channel = val;                    break; @@ -656,11 +784,16 @@ void DList::returnPressed()                    printf("Return pressed in unknown column\n");                    break;              } +       +      if (editEntryOld != *editEntry) +        dcanvas->propagate_drummap_change(editEntry-ourDrumMap); +              selectedColumn = -1;        editor->hide();        editEntry = 0;        setFocus(); -      redraw(); +      MusEGlobal::song->update(SC_DRUMMAP); +      //redraw(); //this is done by the songChanged slot        }  //--------------------------------------------------------- @@ -669,44 +802,65 @@ void DList::returnPressed()  void DList::pitchEdited()  { +      if (editEntry==NULL) +      { +        printf("THIS SHOULD NEVER HAPPEN: editEntry is NULL in DList::pitchEdited()!\n"); +        return; +      } +        int val=pitch_editor->value(); -      int pitch=(editEntry-MusEGlobal::drumMap); +      int instrument=(editEntry-ourDrumMap); +      MusECore::DrumMap editEntryOld=*editEntry;        switch(selectedColumn) { -            case COL_ANOTE: +            case COL_NOTE: +               if (old_style_drummap_mode) //should actually be always true, but to be sure... +               {                      if(val != editEntry->anote)                      {                        MusEGlobal::audio->msgIdle(true); -                      MusEGlobal::song->remapPortDrumCtrlEvents(pitch, val, -1, -1); +                      MusEGlobal::song->remapPortDrumCtrlEvents(instrument, val, -1, -1);                        MusEGlobal::audio->msgIdle(false);                        editEntry->anote = val;                        MusEGlobal::song->update(SC_DRUMMAP);                      } -                  break; - -            case COL_ENOTE: +               } +               else +                  printf("ERROR: THIS SHOULD NEVER HAPPEN: pitch edited of anote in new style mode!\n"); +               break; + +            case COL_INPUTTRIGGER: +               if (old_style_drummap_mode) +               {                    //Check if there is any other MusEGlobal::drumMap with the same inmap value (there should be one (and only one):-)                    //If so, switch the inmap between the instruments -                  for (int i=0; i<DRUM_MAPSIZE; i++) { -                        if (MusEGlobal::drumMap[i].enote == val && &MusEGlobal::drumMap[i] != editEntry) { +                  for (int i=0; i<ourDrumMapSize; i++) { +                        if (ourDrumMap[i].enote == val && &ourDrumMap[i] != editEntry) {                                MusEGlobal::drumInmap[int(editEntry->enote)] = i; -                              MusEGlobal::drumMap[i].enote = editEntry->enote; +                              ourDrumMap[i].enote = editEntry->enote;                                break;                                }                          } -                  //TODO: Set all the notes on the track with pitch=dm->enote to pitch=val -                  editEntry->enote = val; -                  MusEGlobal::drumInmap[val] = pitch; -                  break; +                  //TODO: Set all the notes on the track with instrument=dm->enote to instrument=val +                  MusEGlobal::drumInmap[val] = instrument; +                } +               editEntry->enote = val; +               break; +              default: -                  printf("Value changed in unknown column\n"); +                  printf("ERROR: THIS SHOULD NEVER HAPPEN: Value changed in unknown column\n");                    break;              } +       +      if (editEntryOld != *editEntry) +        dcanvas->propagate_drummap_change(editEntry-ourDrumMap); +              selectedColumn = -1;        pitch_editor->hide();        editEntry = 0;        setFocus(); -      redraw(); +      MusEGlobal::song->update(SC_DRUMMAP); +      //redraw(); //this is done by the songChanged slot        }  //--------------------------------------------------------- @@ -741,14 +895,20 @@ void DList::songChanged(int flags)  //   DList  //--------------------------------------------------------- -DList::DList(QHeaderView* h, QWidget* parent, int ymag) +DList::DList(QHeaderView* h, QWidget* parent, int ymag, DrumCanvas* dcanvas_, bool oldstyle)     : MusEGui::View(parent, 1, ymag)        {        setBg(Qt::white); +       +      dcanvas=dcanvas_; +      ourDrumMap=dcanvas->getOurDrumMap(); +      ourDrumMapSize=dcanvas->getOurDrumMapSize(); +      old_style_drummap_mode=oldstyle; +      connect(dcanvas, SIGNAL(ourDrumMapChanged(bool)), SLOT(ourDrumMapChanged(bool))); +              if (!h){        h = new QHeaderView(Qt::Horizontal, parent);}        header = h; -      scroll = 0;        //ORCAN- CHECK if really needed: header->setTracking(true);        connect(header, SIGNAL(sectionResized(int,int,int)),           SLOT(sizeChange(int,int,int))); @@ -759,7 +919,7 @@ DList::DList(QHeaderView* h, QWidget* parent, int ymag)        pitch_editor = 0;        editEntry = 0;        // always select a drum instrument -      currentlySelected = &MusEGlobal::drumMap[0]; +      currentlySelected = &ourDrumMap[0];        selectedColumn = -1;        } @@ -805,11 +965,21 @@ void DList::viewMouseReleaseEvent(QMouseEvent* ev)        {        if (drag == DRAG) {              int y = ev->y(); -            unsigned dPitch = y / TH; +            int dInstrument; +            if (old_style_drummap_mode) +                  dInstrument = y / TH; +            else +                  dInstrument = (y+TH/2) / TH; +             +            if (dInstrument < 0) dInstrument=0; +            if (dInstrument >= ourDrumMapSize) dInstrument=ourDrumMapSize-1; +             +            int cur_sel = (!old_style_drummap_mode && dInstrument>sInstrument) ? dInstrument-1 : dInstrument; +                          setCursor(QCursor(Qt::ArrowCursor)); -            currentlySelected = &MusEGlobal::drumMap[int(dPitch)]; -            emit curDrumInstrumentChanged(dPitch); -            emit mapChanged(sPitch, dPitch); //Track pitch change done in canvas +            currentlySelected = &ourDrumMap[cur_sel]; +            emit curDrumInstrumentChanged((unsigned)cur_sel); +            emit mapChanged(sInstrument, (unsigned)dInstrument); //Track instrument change done in canvas              }        drag = NORMAL;  //??      redraw();          //commented out NOT by flo93; was already commented out @@ -818,16 +988,16 @@ void DList::viewMouseReleaseEvent(QMouseEvent* ev)        int x = ev->x();        int y = ev->y();        bool shift = ev->modifiers() & Qt::ShiftModifier; -      unsigned pitch = y / TH; +      unsigned instrument = y / TH; -      DCols col = DCols(x2col(x)); +      DrumColumn col = DrumColumn(x2col(x));        switch (col) {              case COL_NAME: -                  emit keyReleased(pitch, shift); +                  emit keyReleased(instrument, shift);                    break; -            case COL_ANOTE: -                  emit keyReleased(pitch, shift); +            case COL_NOTE: +                  emit keyReleased(instrument, shift);                    break;              default:                    break; @@ -845,4 +1015,21 @@ int DList::getSelectedInstrument()        return MusEGlobal::drumInmap[int(currentlySelected->enote)];        } + +void DList::ourDrumMapChanged(bool instrMapChanged) +{ +  int selIdx = currentlySelected - ourDrumMap; +   +  ourDrumMap=dcanvas->getOurDrumMap(); +  ourDrumMapSize=dcanvas->getOurDrumMapSize(); +   +  if (instrMapChanged) +    editEntry=NULL; +   +  if (selIdx >= ourDrumMapSize) selIdx=ourDrumMapSize-1; +  currentlySelected = &ourDrumMap[selIdx]; + +  redraw(); +} +  } // namespace MusEGui diff --git a/muse2/muse/midiedit/dlist.h b/muse2/muse/midiedit/dlist.h index 99e9460f..35a67023 100644 --- a/muse2/muse/midiedit/dlist.h +++ b/muse2/muse/midiedit/dlist.h @@ -35,6 +35,8 @@ class QHeaderView;  class QLineEdit;  class QMouseEvent;  class QPainter; +class Device; +class QLineEdit;  namespace MusECore {  class DrumMap; @@ -43,6 +45,7 @@ class DrumMap;  namespace MusEGui {  class ScrollScale; +class DrumCanvas;  //---------------------------------------------------------  //   DLineEdit @@ -89,9 +92,13 @@ class DPitchEdit: public Awl::PitchEdit  class DList : public View {        Q_OBJECT -     +       +      MusEGui::DrumCanvas* dcanvas; +      MusECore::DrumMap* ourDrumMap; +      int ourDrumMapSize; +      bool old_style_drummap_mode; +              QHeaderView* header; -      ScrollScale* scroll;        QLineEdit* editor;        DPitchEdit* pitch_editor;        MusECore::DrumMap* editEntry; @@ -101,7 +108,7 @@ class DList : public View {        int startY;        int curY; -      int sPitch; +      int sInstrument;        enum { NORMAL, START_DRAG, DRAG } drag;        virtual void draw(QPainter& p, const QRect&); @@ -131,18 +138,16 @@ class DList : public View {     public slots:        void tracklistChanged();        void songChanged(int); +      void ourDrumMapChanged(bool); +        public:        void lineEdit(int line, int section);        void pitchEdit(int line, int section);        void setCurDrumInstrument(int n); -      DList(QHeaderView*, QWidget* parent, int ymag); +      DList(QHeaderView*, QWidget* parent, int ymag, MusEGui::DrumCanvas* dcanvas, bool oldstyle);        ~DList(); -      void setScroll(ScrollScale* s) { scroll = s; }        int getSelectedInstrument(); -enum DCols { COL_MUTE=0, COL_NAME, COL_VOL, COL_QNT, COL_ENOTE, COL_LEN, -         COL_ANOTE, COL_CHANNEL, COL_PORT, -         COL_LV1, COL_LV2, COL_LV3, COL_LV4, COL_NONE=-1};        };  } // namespace MusEGui diff --git a/muse2/muse/midiedit/drumedit.cpp b/muse2/muse/midiedit/drumedit.cpp index 4a234481..3a75e32d 100644 --- a/muse2/muse/midiedit/drumedit.cpp +++ b/muse2/muse/midiedit/drumedit.cpp @@ -82,27 +82,12 @@ static const char* map_file_save_pattern[] = {  int DrumEdit::_rasterInit = 96;  int DrumEdit::_dlistWidthInit = 50;  int DrumEdit::_dcanvasWidthInit = 300; +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; -enum DrumColumn { -  COL_MUTE = 0, -  COL_NAME, -  COL_VOLUME, -  COL_QUANT, -  COL_INPUTTRIGGER, -  COL_NOTELENGTH, -  COL_NOTE, -  COL_OUTCHANNEL, -  COL_OUTPORT, -  COL_LEVEL1, -  COL_LEVEL2, -  COL_LEVEL3, -  COL_LEVEL4, -  COL_NONE = -1 -};  //---------------------------------------------------------  //   setHeaderWhatsThis @@ -110,6 +95,7 @@ enum DrumColumn {  void DrumEdit::setHeaderWhatsThis()        { +      header->setWhatsThis(COL_HIDE, tr("hide instrument"));        header->setWhatsThis(COL_MUTE, tr("mute instrument"));        header->setWhatsThis(COL_NAME, tr("sound name"));        header->setWhatsThis(COL_VOLUME, tr("volume percent")); @@ -131,6 +117,7 @@ void DrumEdit::setHeaderWhatsThis()  void DrumEdit::setHeaderToolTips()        { +      header->setToolTip(COL_HIDE, tr("hide instrument"));        header->setToolTip(COL_MUTE, tr("mute instrument"));        header->setToolTip(COL_NAME, tr("sound name"));        header->setToolTip(COL_VOLUME, tr("volume percent")); @@ -179,6 +166,9 @@ DrumEdit::DrumEdit(MusECore::PartList* pl, QWidget* parent, const char* name, un        selPart  = 0;        QSignalMapper *signalMapper = new QSignalMapper(this); +      _group_mode = GROUP_SAME_CHANNEL; +      _ignore_hide = _ignore_hide_init; +              //---------Pulldown Menu----------------------------        menuFile = menuBar()->addMenu(tr("&File")); @@ -255,8 +245,14 @@ DrumEdit::DrumEdit(MusECore::PartList* pl, QWidget* parent, const char* name, un        menuFunctions->setTearOffEnabled(true); -      QAction* reorderListAction = menuFunctions->addAction(tr("Re-order list")); -      menuFunctions->addSeparator(); +      if (old_style_drummap_mode()) +      { +        QAction* reorderListAction = menuFunctions->addAction(tr("Re-order list")); +        connect(reorderListAction, SIGNAL(triggered()), signalMapper, SLOT(map())); +        signalMapper->setMapping(reorderListAction, DrumCanvas::CMD_REORDER_LIST); +        menuFunctions->addSeparator(); +      } +        fixedAction = menuFunctions->addAction(tr("Set Fixed Length"));        veloAction = menuFunctions->addAction(tr("Modify Velocity"));        crescAction = menuFunctions->addAction(tr("Crescendo/Decrescendo")); @@ -265,7 +261,6 @@ DrumEdit::DrumEdit(MusECore::PartList* pl, QWidget* parent, const char* name, un        QAction* noteShiftAction = menuFunctions->addAction(tr("Move Notes"));        QAction* delOverlapsAction = menuFunctions->addAction(tr("Delete Overlaps")); -      connect(reorderListAction, SIGNAL(triggered()), signalMapper, SLOT(map()));        connect(fixedAction, SIGNAL(triggered()), signalMapper, SLOT(map()));        connect(veloAction, SIGNAL(triggered()), signalMapper, SLOT(map()));        connect(crescAction, SIGNAL(triggered()), signalMapper, SLOT(map())); @@ -274,7 +269,6 @@ DrumEdit::DrumEdit(MusECore::PartList* pl, QWidget* parent, const char* name, un        connect(noteShiftAction, SIGNAL(triggered()), signalMapper, SLOT(map()));        connect(delOverlapsAction, SIGNAL(triggered()), signalMapper, SLOT(map())); -      signalMapper->setMapping(reorderListAction, DrumCanvas::CMD_REORDER_LIST);        signalMapper->setMapping(fixedAction, DrumCanvas::CMD_FIXED_LEN);        signalMapper->setMapping(veloAction, DrumCanvas::CMD_MODIFY_VELOCITY);        signalMapper->setMapping(crescAction, DrumCanvas::CMD_CRESCENDO); @@ -283,10 +277,44 @@ DrumEdit::DrumEdit(MusECore::PartList* pl, QWidget* parent, const char* name, un        signalMapper->setMapping(noteShiftAction, DrumCanvas::CMD_NOTE_SHIFT);        signalMapper->setMapping(delOverlapsAction, DrumCanvas::CMD_DELETE_OVERLAPS); + +        QMenu* menuScriptPlugins = menuBar()->addMenu(tr("&Plugins"));        MusEGlobal::song->populateScriptMenu(menuScriptPlugins, this);        QMenu* settingsMenu = menuBar()->addMenu(tr("Window &Config")); +      if (!old_style_drummap_mode()) +      { +        QMenu* menuGrouping=settingsMenu->addMenu(tr("Group")); +        groupNoneAction = menuGrouping->addAction(tr("Don't group")); +        groupChanAction = menuGrouping->addAction(tr("Group by channel")); +        groupMaxAction  = menuGrouping->addAction(tr("Group maximally")); +        QAction* ignoreHideAction = settingsMenu->addAction(tr("Also show hidden events")); +        settingsMenu->addSeparator(); +         +        groupNoneAction->setCheckable(true); +        groupChanAction->setCheckable(true); +        groupMaxAction ->setCheckable(true); +        ignoreHideAction->setCheckable(true); +        ignoreHideAction->setChecked(_ignore_hide); +         +        connect(groupNoneAction, SIGNAL(triggered()), signalMapper, SLOT(map())); +        connect(groupChanAction, SIGNAL(triggered()), signalMapper, SLOT(map())); +        connect(groupMaxAction,  SIGNAL(triggered()), signalMapper, SLOT(map())); +        connect(ignoreHideAction,  SIGNAL(toggled(bool)), SLOT(set_ignore_hide(bool))); + +        signalMapper->setMapping(groupNoneAction, DrumCanvas::CMD_GROUP_NONE); +        signalMapper->setMapping(groupChanAction, DrumCanvas::CMD_GROUP_CHAN); +        signalMapper->setMapping(groupMaxAction,  DrumCanvas::CMD_GROUP_MAX); +         +        updateGroupingActions(); +      } +      else +      { +        groupNoneAction=NULL; +        groupChanAction=NULL; +        groupMaxAction =NULL; +      }        settingsMenu->addAction(subwinAction);        settingsMenu->addAction(shareAction);        settingsMenu->addAction(fullscreenAction); @@ -408,7 +436,7 @@ DrumEdit::DrumEdit(MusECore::PartList* pl, QWidget* parent, const char* name, un        gridS2->setSpacing(0);          time                = new MusEGui::MTScale(&_raster, split1w2, xscale);        canvas              = new DrumCanvas(this, split1w2, xscale, yscale); -      vscroll             = new MusEGui::ScrollScale(-4, 1, yscale, DRUM_MAPSIZE*TH, Qt::Vertical, split1w2); +      vscroll             = new MusEGui::ScrollScale(-4, 1, yscale, dynamic_cast<DrumCanvas*>(canvas)->getOurDrumMapSize()*TH, Qt::Vertical, split1w2);        int offset = -(MusEGlobal::config.division/4);        canvas->setOrigin(offset, 0);        canvas->setCanvasTools(drumeditTools); @@ -416,6 +444,7 @@ DrumEdit::DrumEdit(MusECore::PartList* pl, QWidget* parent, const char* name, un        connect(canvas, SIGNAL(toolChanged(int)), tools2, SLOT(set(int)));        connect(canvas, SIGNAL(horizontalZoomIn()), SLOT(horizontalZoomIn()));        connect(canvas, SIGNAL(horizontalZoomOut()), SLOT(horizontalZoomOut())); +      connect(canvas, SIGNAL(ourDrumMapChanged(bool)), SLOT(ourDrumMapChanged(bool)));        time->setOrigin(offset, 0);        QList<int> mops; @@ -439,6 +468,7 @@ DrumEdit::DrumEdit(MusECore::PartList* pl, QWidget* parent, const char* name, un        //        header = new MusEGui::Header(split1w1, "header");        header->setFixedHeight(31); +      header->setColumnLabel(tr("H"), COL_HIDE, 20);        header->setColumnLabel(tr("M"), COL_MUTE, 20);        header->setColumnLabel(tr("Sound"), COL_NAME, 120);        header->setColumnLabel(tr("Vol"), COL_VOLUME); @@ -456,7 +486,18 @@ DrumEdit::DrumEdit(MusECore::PartList* pl, QWidget* parent, const char* name, un        setHeaderToolTips();        setHeaderWhatsThis(); -      dlist = new DList(header, split1w1, yscale); +      if (!old_style_drummap_mode()) +      { +        header->hideSection(COL_OUTPORT); +        header->hideSection(COL_OUTCHANNEL); +      } +       +      if (!old_style_drummap_mode() && _ignore_hide) +        header->showSection(COL_HIDE); +      else +        header->hideSection(COL_HIDE); + +      dlist = new DList(header, split1w1, yscale, (DrumCanvas*)canvas, old_style_drummap_mode());        // p3.3.44        setCurDrumInstrument(dlist->getSelectedInstrument()); @@ -546,8 +587,12 @@ void DrumEdit::songChanged1(int bits)              toolbar->setSolo(canvas->track()->solo());              return;          }       +        if ( !old_style_drummap_mode() &&  +             ( bits & (SC_DRUMMAP | SC_TRACK_INSERTED | SC_TRACK_REMOVED | SC_TRACK_MODIFIED | +                       SC_PART_INSERTED | SC_PART_REMOVED | SC_PART_MODIFIED) ) ) +          ((DrumCanvas*)(canvas))->rebuildOurDrumMap(); +                  songChanged(bits); -        }  //--------------------------------------------------------- @@ -704,6 +749,7 @@ void DrumEdit::writeStatus(int level, MusECore::Xml& xml) const        xml.intTag(level, "xmag", hscroll->mag());        xml.intTag(level, "ypos", vscroll->pos());        xml.intTag(level, "ymag", vscroll->mag()); +      xml.intTag(level, "ignore_hide", _ignore_hide);        xml.tag(level, "/drumedit");        } @@ -751,6 +797,8 @@ void DrumEdit::readStatus(MusECore::Xml& xml)                                vscroll->setMag(xml.parseInt());                          else if (tag == "ypos")                                vscroll->setPos(xml.parseInt()); +                        else if (tag == "ignore_hide") +                              _ignore_hide=xml.parseInt();                          else                                xml.unknown("DrumEdit");                          break; @@ -787,6 +835,8 @@ void DrumEdit::readConfiguration(MusECore::Xml& xml)                                _dcanvasWidthInit = xml.parseInt();                          else if (tag == "dlistwidth")                                _dlistWidthInit = xml.parseInt(); +                        else if (tag == "ignore_hide_init") +                              _ignore_hide_init = xml.parseInt();                          else if (tag == "topwin")                                TopWin::readConfiguration(DRUM, xml);                          else @@ -812,6 +862,7 @@ void DrumEdit::writeConfiguration(int level, MusECore::Xml& xml)        xml.intTag(level, "raster", _rasterInit);        xml.intTag(level, "dlistwidth", _dlistWidthInit);        xml.intTag(level, "dcanvaswidth", _dcanvasWidthInit); +      xml.intTag(level, "ignore_hide_init", _ignore_hide_init);        TopWin::writeConfiguration(DRUM, level,xml);        xml.tag(level, "/drumedit");        } @@ -953,7 +1004,11 @@ void DrumEdit::cmd(int cmd)              case DrumCanvas::CMD_REORDER_LIST: ((DrumCanvas*)(canvas))->moveAwayUnused(); break;              //case DrumCanvas::CMD_FIXED_LEN: // this must be handled by the drum canvas, due to its                                                // special nature (each drum has its own length) - +             +            case DrumCanvas::CMD_GROUP_NONE: _group_mode=DONT_GROUP; updateGroupingActions(); ((DrumCanvas*)(canvas))->rebuildOurDrumMap(); break; +            case DrumCanvas::CMD_GROUP_CHAN: _group_mode=GROUP_SAME_CHANNEL; updateGroupingActions(); ((DrumCanvas*)(canvas))->rebuildOurDrumMap(); break; +            case DrumCanvas::CMD_GROUP_MAX: _group_mode=GROUP_MAX; updateGroupingActions(); ((DrumCanvas*)(canvas))->rebuildOurDrumMap(); break; +                          default: ((DrumCanvas*)(canvas))->cmd(cmd);              }        } @@ -1128,7 +1183,7 @@ void DrumEdit::keyPressEvent(QKeyEvent* event)              return;        }        else if (key == Qt::Key_F2) { -            dlist->lineEdit(dlist->getSelectedInstrument(),(int)DList::COL_NAME); +            dlist->lineEdit(dlist->getSelectedInstrument(),(int)COL_NAME);              return;              }        else if (key == shortcuts[SHRT_INSTRUMENT_STEP_UP].key) { @@ -1325,4 +1380,51 @@ void DrumEdit::setStep(QString v)    canvas->setFocus();  } +bool DrumEdit::old_style_drummap_mode() +{ +  for (MusECore::ciPart p = parts()->begin(); p != parts()->end(); ++p) +    if (p->second->track()->type()==MusECore::Track::DRUM) +      return true; +   +  return false; +} + +void DrumEdit::ourDrumMapChanged(bool instrMapChanged) +{ +  if (instrMapChanged) +  { +    int vmin,vmax; +    vscroll->range(&vmin, &vmax); +    vscroll->setRange(vmin, dynamic_cast<DrumCanvas*>(canvas)->getOurDrumMapSize()*TH); +  } +} + +void DrumEdit::updateGroupingActions() +{ +  if (groupNoneAction==NULL || groupChanAction==NULL || groupMaxAction==NULL) +  { +    printf("THIS SHOULD NEVER HAPPEN: DrumEdit::updateGroupingActions() called, but one of the actions is NULL!\n"); +    return; +  } +   +  groupNoneAction->setChecked(_group_mode==DONT_GROUP); +  groupChanAction->setChecked(_group_mode==GROUP_SAME_CHANNEL); +  groupMaxAction ->setChecked(_group_mode==GROUP_MAX); +} + +void DrumEdit::set_ignore_hide(bool val) +{ +  _ignore_hide=val; +  _ignore_hide_init=val; +  // this may only called be from the action's toggled signal. +  // if called otherwise, the action's checked state isn't updated! + +  if (!old_style_drummap_mode() && _ignore_hide) +    header->showSection(COL_HIDE); +  else +    header->hideSection(COL_HIDE); +   +  ((DrumCanvas*)(canvas))->rebuildOurDrumMap(); +} +  } // namespace MusEGui diff --git a/muse2/muse/midiedit/drumedit.h b/muse2/muse/midiedit/drumedit.h index 1ca6f989..5603e449 100644 --- a/muse2/muse/midiedit/drumedit.h +++ b/muse2/muse/midiedit/drumedit.h @@ -64,6 +64,23 @@ class ScrollScale;  class Splitter;  class Toolbar1; +enum DrumColumn { +  COL_HIDE = 0, +  COL_MUTE, +  COL_NAME, +  COL_VOLUME, +  COL_QUANT, +  COL_INPUTTRIGGER, +  COL_NOTELENGTH, +  COL_NOTE, +  COL_OUTCHANNEL, +  COL_OUTPORT, +  COL_LEVEL1, +  COL_LEVEL2, +  COL_LEVEL3, +  COL_LEVEL4, +  COL_NONE = -1 +};  //---------------------------------------------------------  //   DrumEdit @@ -71,7 +88,14 @@ class Toolbar1;  class DrumEdit : public MidiEditor {        Q_OBJECT -     + +   public: +      enum group_mode_t { DONT_GROUP, GROUP_SAME_CHANNEL, GROUP_MAX }; +   +   private: +      group_mode_t _group_mode; +      bool _ignore_hide; +              MusECore::Event selEvent;        MusECore::MidiPart* selPart;        int selTick; @@ -93,13 +117,14 @@ class DrumEdit : public MidiEditor {        static int _rasterInit;        static int _dlistWidthInit, _dcanvasWidthInit; +      static bool _ignore_hide_init;        QAction *loadAction, *saveAction, *resetAction;        QAction *cutAction, *copyAction, *copyRangeAction, *pasteAction, *pasteDialogAction, *deleteAction;        QAction *fixedAction, *veloAction, *crescAction, *quantizeAction;        QAction *sallAction, *snoneAction, *invAction, *inAction , *outAction;        QAction *prevAction, *nextAction; - +      QAction *groupNoneAction, *groupChanAction, *groupMaxAction;        void initShortcuts(); @@ -127,6 +152,8 @@ class DrumEdit : public MidiEditor {        void configChanged();        void songChanged1(int);        void setStep(QString); +      void updateGroupingActions(); +      void set_ignore_hide(bool);     public slots:        void setSelection(int, MusECore::Event&, MusECore::Part*); @@ -134,8 +161,9 @@ class DrumEdit : public MidiEditor {        void execDeliveredScript(int);        void execUserScript(int);        CtrlEdit* addCtrl(); -       +      void ourDrumMapChanged(bool);        virtual void updateHScrollRange(); +     signals:        void deleted(MusEGui::TopWin*); @@ -146,6 +174,10 @@ class DrumEdit : public MidiEditor {        virtual void writeStatus(int, MusECore::Xml&) const;        static void readConfiguration(MusECore::Xml& xml);        static void writeConfiguration(int, MusECore::Xml&); +       +      bool old_style_drummap_mode(); +      group_mode_t group_mode() { return _group_mode; } +      bool ignore_hide() { return _ignore_hide; }        };  } // namespace MusEGui diff --git a/muse2/muse/midiedit/drummap.cpp b/muse2/muse/midiedit/drummap.cpp index aa7ce759..9d4b23c2 100644 --- a/muse2/muse/midiedit/drummap.cpp +++ b/muse2/muse/midiedit/drummap.cpp @@ -26,10 +26,12 @@  #include "xml.h"  #include "song.h" +  namespace MusEGlobal {  char drumOutmap[DRUM_MAPSIZE];  char drumInmap[128];  MusECore::DrumMap drumMap[DRUM_MAPSIZE]; +global_drum_ordering_t global_drum_ordering;  }  namespace MusECore { diff --git a/muse2/muse/midiedit/drummap.h b/muse2/muse/midiedit/drummap.h index 60a25fad..2dbaae42 100644 --- a/muse2/muse/midiedit/drummap.h +++ b/muse2/muse/midiedit/drummap.h @@ -24,7 +24,8 @@  #ifndef __DRUMMAP_H__  #define __DRUMMAP_H__ -class QString; +#include <QString> +#include <QList>  namespace MusECore { @@ -46,23 +47,28 @@ struct DrumMap {        bool mute;  //      bool selected; -      //bool const operator==(const DrumMap& map) const;        bool operator==(const DrumMap& map) const; +      bool operator!=(const DrumMap& map) const { return !operator==(map); }        };  #define DRUM_MAPSIZE  128 +extern const DrumMap idrumMap[DRUM_MAPSIZE]; //FINDMICH dummy!  extern void initDrumMap();  extern void writeDrumMap(int level, Xml& xml, bool external);  extern void readDrumMap(Xml& xml, bool external);  extern void resetGMDrumMap(); +class MidiTrack;  } // namespace MusECore  namespace MusEGlobal {  extern char drumOutmap[DRUM_MAPSIZE];  extern char drumInmap[DRUM_MAPSIZE];  extern MusECore::DrumMap drumMap[DRUM_MAPSIZE]; +typedef QList< std::pair<MusECore::MidiTrack*,int> > global_drum_ordering_t; + +extern global_drum_ordering_t global_drum_ordering;  }  #endif diff --git a/muse2/muse/midiedit/prcanvas.cpp b/muse2/muse/midiedit/prcanvas.cpp index a70c4a91..9acaf186 100644 --- a/muse2/muse/midiedit/prcanvas.cpp +++ b/muse2/muse/midiedit/prcanvas.cpp @@ -112,6 +112,10 @@ PianoCanvas::PianoCanvas(MidiEditor* pr, QWidget* parent, int sx, int sy)        connect(MusEGlobal::song, SIGNAL(midiNote(int, int)), SLOT(midiNote(int,int)));        } +PianoCanvas::~PianoCanvas() +{ +  delete steprec; +}  //---------------------------------------------------------  //   pitch2y  //--------------------------------------------------------- diff --git a/muse2/muse/midiedit/prcanvas.h b/muse2/muse/midiedit/prcanvas.h index 13effc19..18d4f130 100644 --- a/muse2/muse/midiedit/prcanvas.h +++ b/muse2/muse/midiedit/prcanvas.h @@ -120,6 +120,7 @@ class PianoCanvas : public EventCanvas {           };        PianoCanvas(MidiEditor*, QWidget*, int, int); +      virtual ~PianoCanvas();        void cmd(int cmd);        void setColorMode(int mode) {              colorMode = mode; diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index ab161946..d09ebc34 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -1258,6 +1258,11 @@ ScoreCanvas::ScoreCanvas(ScoreEdit* pr, QWidget* parent_widget) : View(parent_wi  	unsetCursor();  } +ScoreCanvas::~ScoreCanvas() +{ +	delete steprec; +} +  void ScoreCanvas::staffmode_treble_slot()  {  	set_staffmode(current_staff, MODE_TREBLE); @@ -4584,16 +4589,43 @@ void ScoreCanvas::add_new_parts(const std::map< MusECore::Part*, std::set<MusECo   *     because after A (and B) got resized, the B-resize is invalid!   *   o when changing toolbarstate when sharing and immediately after that   *     changing "share" status, the changed state isn't stored + *   o arranger state and mixer state aren't stored (says tim)   *   ? pasting in editors sometimes fails oO? ( ERROR: reading eventlist   *     from clipboard failed. ignoring this one... ) [ not reproducible ]   *    * CURRENT TODO - * ! o fix sigedit boxes (see also "important todo") + *   o in appearance.cpp: add the new stuff for drumTrackLabelBg and drumTrackBg  + *   o find and fix FINDMICHJETZT + *   o fix all segfaults and non-working stuff! + *        - creating, changing types to and from, erasing NEW_DRUM tracks + *        - move parts around + *        - playing them. mute? + *        - recording/echoing/steprec them + *        - load, save them   *   o fix valgrind problems + *    * > o drum editor: channel-stuff + *        o clearly state in the changelog: when having multiple drumeditors open, + *          the mute-column may not work, because another editor is overriding this. + *        o respect "_drummap_tied_to_patch": IMPLEMENT + *        o save hide, ordering, track's drumlists + * 				o "copy drumlist" from one track to another + *        o whenever changing the patch and maintained_automatically==true, + *          the drumlist is replaced by the according one (for example, "jazz" drum kit's list) + *        o whenever changing the drumlist and maintained_automatically==true, + *          ask the user if he wants to proceed, and then set maintained_automatically to false + *        o offer some way to set maintained_automatically to true again + *        o move generation and deletion of ourDrumMap from DCanvas to DrumEditor and remove ugly wrapper functions + * + *   o when playing back a flo-drum-track: treat as a MIDI track, + *     EXCEPT that the drum list's mute entries are respected! + *   o when recording or echoing a flo-drum-track: watch out for In-Notes! + *   o update [midi]track::read/write, readproperties, writeprop... (drumlist etc), operator=   *   * IMPORTANT TODO - * ! o fix sigedit boxes (see also "current todo") + *   o all places where i added doubleclick-edits: only react on left-click double clicks! + *   o support "new style" reordering with old style drum tracks as well + *     (not swapping but inserting!)   *   o add "dotted quarter" quantize option (for 6/8 beat)   *   o ticks-to-quarter spinboxes   *   o newly created windows have to be focussed! diff --git a/muse2/muse/midiedit/scoreedit.h b/muse2/muse/midiedit/scoreedit.h index 4e2ecf5d..0d1432b8 100644 --- a/muse2/muse/midiedit/scoreedit.h +++ b/muse2/muse/midiedit/scoreedit.h @@ -811,7 +811,7 @@ class ScoreCanvas : public MusEGui::View  	public:  		ScoreCanvas(ScoreEdit*, QWidget*); -		~ScoreCanvas(){}; +		~ScoreCanvas();  		void add_staves(MusECore::PartList* pl, bool all_in_one);  		void push_back_staff(staff_t& staff) { staves.push_back(staff); } //FINDMICH dirty. very dirty. diff --git a/muse2/muse/mixer/amixer.cpp b/muse2/muse/mixer/amixer.cpp index 3a947945..64ebda11 100644 --- a/muse2/muse/mixer/amixer.cpp +++ b/muse2/muse/mixer/amixer.cpp @@ -183,6 +183,7 @@ AudioMixerApp::AudioMixerApp(QWidget* parent, MixerConfig* c)        showMidiTracksId = new QAction(tr("Show Midi Tracks"), actionItems);        showDrumTracksId = new QAction(tr("Show Drum Tracks"), actionItems); +      showNewDrumTracksId = new QAction(tr("Show New Style Drum Tracks"), actionItems);        showWaveTracksId = new QAction(tr("Show Wave Tracks"), actionItems);        QAction *separator = new QAction(this); @@ -197,6 +198,7 @@ AudioMixerApp::AudioMixerApp(QWidget* parent, MixerConfig* c)        showMidiTracksId->setCheckable(true);        showDrumTracksId->setCheckable(true); +      showNewDrumTracksId->setCheckable(true);        showWaveTracksId->setCheckable(true);        showInputTracksId->setCheckable(true);        showOutputTracksId->setCheckable(true); @@ -208,6 +210,7 @@ AudioMixerApp::AudioMixerApp(QWidget* parent, MixerConfig* c)        //connect(actionItems, SIGNAL(selected(QAction*)), this, SLOT(showTracksChanged(QAction*)));        connect(showMidiTracksId, SIGNAL(triggered(bool)), SLOT(showMidiTracksChanged(bool)));        connect(showDrumTracksId, SIGNAL(triggered(bool)), SLOT(showDrumTracksChanged(bool)));       +      connect(showNewDrumTracksId, SIGNAL(triggered(bool)), SLOT(showNewDrumTracksChanged(bool)));              connect(showWaveTracksId, SIGNAL(triggered(bool)), SLOT(showWaveTracksChanged(bool)));              connect(showInputTracksId, SIGNAL(triggered(bool)), SLOT(showInputTracksChanged(bool)));              connect(showOutputTracksId, SIGNAL(triggered(bool)), SLOT(showOutputTracksChanged(bool)));       @@ -349,6 +352,7 @@ void AudioMixerApp::updateMixer(UpdateAction action)        showMidiTracksId->setChecked(cfg->showMidiTracks);        showDrumTracksId->setChecked(cfg->showDrumTracks); +      showNewDrumTracksId->setChecked(cfg->showNewDrumTracks);        showInputTracksId->setChecked(cfg->showInputTracks);        showOutputTracksId->setChecked(cfg->showOutputTracks);        showWaveTracksId->setChecked(cfg->showWaveTracks); @@ -428,7 +432,7 @@ void AudioMixerApp::updateMixer(UpdateAction action)              for (MusECore::iMidiTrack i = mtl->begin(); i != mtl->end(); ++i)               {                MusECore::MidiTrack* mt = *i; -              if((mt->type() == MusECore::Track::MIDI && cfg->showMidiTracks) || (mt->type() == MusECore::Track::DRUM && cfg->showDrumTracks))  +              if((mt->type() == MusECore::Track::MIDI && cfg->showMidiTracks) || (mt->type() == MusECore::Track::DRUM && cfg->showDrumTracks) || (mt->type() == MusECore::Track::NEW_DRUM && cfg->showNewDrumTracks))                   addStrip(*i, idx++);              } @@ -485,7 +489,7 @@ void AudioMixerApp::updateMixer(UpdateAction action)        for (MusECore::iMidiTrack i = mtl->begin(); i != mtl->end(); ++i)         {          MusECore::MidiTrack* mt = *i; -        if((mt->type() == MusECore::Track::MIDI && cfg->showMidiTracks) || (mt->type() == MusECore::Track::DRUM && cfg->showDrumTracks))  +        if((mt->type() == MusECore::Track::MIDI && cfg->showMidiTracks) || (mt->type() == MusECore::Track::DRUM && cfg->showDrumTracks) || (mt->type() == MusECore::Track::NEW_DRUM && cfg->showNewDrumTracks))             addStrip(*i, idx++);        } @@ -627,6 +631,8 @@ void AudioMixerApp::showTracksChanged(QAction* id)              cfg->showMidiTracks = val;        else if (id == showDrumTracksId)              cfg->showDrumTracks = val; +      else if (id == showNewDrumTracksId) +            cfg->showNewDrumTracks = val;        else if (id == showInputTracksId)              cfg->showInputTracks = val;        else if (id == showOutputTracksId) @@ -655,6 +661,12 @@ void AudioMixerApp::showDrumTracksChanged(bool v)        updateMixer(UPDATE_ALL);  } +void AudioMixerApp::showNewDrumTracksChanged(bool v) +{ +      cfg->showNewDrumTracks = v; +      updateMixer(UPDATE_ALL); +} +  void AudioMixerApp::showWaveTracksChanged(bool v)  {        cfg->showWaveTracks = v; @@ -710,6 +722,7 @@ void AudioMixerApp::write(int level, MusECore::Xml& xml)        xml.intTag(level, "showMidiTracks",   cfg->showMidiTracks);        xml.intTag(level, "showDrumTracks",   cfg->showDrumTracks); +      xml.intTag(level, "showNewDrumTracks",   cfg->showNewDrumTracks);        xml.intTag(level, "showInputTracks",  cfg->showInputTracks);        xml.intTag(level, "showOutputTracks", cfg->showOutputTracks);        xml.intTag(level, "showWaveTracks",   cfg->showWaveTracks); diff --git a/muse2/muse/mixer/amixer.h b/muse2/muse/mixer/amixer.h index cf856f22..1f29c693 100644 --- a/muse2/muse/mixer/amixer.h +++ b/muse2/muse/mixer/amixer.h @@ -96,6 +96,7 @@ class AudioMixerApp : public QMainWindow {        QAction* showMidiTracksId;        QAction* showDrumTracksId; +      QAction* showNewDrumTracksId;        QAction* showInputTracksId;        QAction* showOutputTracksId;        QAction* showWaveTracksId; @@ -129,6 +130,7 @@ class AudioMixerApp : public QMainWindow {        //void showTracksChanged(QAction*);        void showMidiTracksChanged(bool);        void showDrumTracksChanged(bool); +      void showNewDrumTracksChanged(bool);        void showWaveTracksChanged(bool);        void showInputTracksChanged(bool);        void showOutputTracksChanged(bool); diff --git a/muse2/muse/mixer/strip.cpp b/muse2/muse/mixer/strip.cpp index b87c4629..5f5e5e39 100644 --- a/muse2/muse/mixer/strip.cpp +++ b/muse2/muse/mixer/strip.cpp @@ -150,6 +150,10 @@ void Strip::setLabelText()                    //c = QColor(0, 160, 255); // Med blue                    c = MusEGlobal::config.drumTrackLabelBg;                    break; +            case MusECore::Track::NEW_DRUM: +                  //c = QColor(0, 160, 255); // Med blue +                  c = MusEGlobal::config.newDrumTrackLabelBg; +                  break;              default:                    return;                    } diff --git a/muse2/muse/part.cpp b/muse2/muse/part.cpp index 693512c5..3601ff57 100644 --- a/muse2/muse/part.cpp +++ b/muse2/muse/part.cpp @@ -403,7 +403,7 @@ void addPortCtrlEvents(Event& event, Part* part, bool doClones)              MidiPort* mp = &MusEGlobal::midiPorts[port];              // Is it a drum controller event, according to the track port's instrument? -            if(mt->type() == Track::DRUM) +            if(mt->type() == Track::DRUM) //FINDMICHJETZT was ist das?              {                MidiController* mc = mp->drumController(cntrl);                if(mc) @@ -471,7 +471,7 @@ void addPortCtrlEvents(Part* part, bool doClones)              MidiPort* mp = &MusEGlobal::midiPorts[port];              // Is it a drum controller event, according to the track port's instrument? -            if(mt->type() == Track::DRUM) +            if(mt->type() == Track::DRUM) //FINDMICHJETZT was ist das?              {                MidiController* mc = mp->drumController(cntrl);                if(mc) @@ -530,7 +530,7 @@ void removePortCtrlEvents(Event& event, Part* part, bool doClones)              MidiPort* mp = &MusEGlobal::midiPorts[port];              // Is it a drum controller event, according to the track port's instrument? -            if(mt->type() == Track::DRUM) +            if(mt->type() == Track::DRUM) //FINDMICHJETZT was ist das?              {                MidiController* mc = mp->drumController(cntrl);                if(mc) @@ -599,7 +599,7 @@ void removePortCtrlEvents(Part* part, bool doClones)              MidiPort* mp = &MusEGlobal::midiPorts[port];              // Is it a drum controller event, according to the track port's instrument? -            if(mt->type() == Track::DRUM) +            if(mt->type() == Track::DRUM) //FINDMICHJETZT was ist das?              {                MidiController* mc = mp->drumController(cntrl);                if(mc) @@ -917,6 +917,7 @@ void Song::cmdResizePart(Track* track, Part* oPart, unsigned int len, bool doClo                    break;              case Track::MIDI:              case Track::DRUM: +            case Track::NEW_DRUM:                    {                    Undo operations; @@ -963,6 +964,7 @@ void Track::splitPart(Part* part, int tickpos, Part*& p1, Part*& p2)                    break;              case MIDI:              case DRUM: +            case NEW_DRUM:                    l1 = tickpos - part->tick();                    l2 = part->lenTick() - l1;                    break; @@ -986,6 +988,7 @@ void Track::splitPart(Part* part, int tickpos, Part*& p1, Part*& p2)                    break;              case MIDI:              case DRUM: +            case NEW_DRUM:                    p1->setLenTick(l1);                    p2->setTick(tickpos);                    p2->setLenTick(l2); diff --git a/muse2/muse/remote/pyapi.cpp b/muse2/muse/remote/pyapi.cpp index 645c639e..57b956ca 100644 --- a/muse2/muse/remote/pyapi.cpp +++ b/muse2/muse/remote/pyapi.cpp @@ -697,7 +697,8 @@ PyObject* getAudioTrackVolume(PyObject*, PyObject* args)        if (t == NULL)              return NULL; -      if (t->type() == Track::DRUM || t->type() == Track::MIDI) +      //if (t->type() == Track::DRUM || t->type() == Track::MIDI || t->type() == Track::NEW_DRUM) +        if (t->isMidiTrack()) // changed by flo. should do the same thing and is better maintainable              return NULL;        AudioTrack* track = (AudioTrack*) t; @@ -1091,7 +1092,8 @@ bool Song::event(QEvent* _e)                    if (t == NULL)                          return false; -                  if (t->type() == Track::DRUM || t->type() == Track::MIDI) +                  if (t->isMidiTrack()) // changed by flo. is better maintainable +                  //if (t->type() == Track::DRUM || t->type() == Track::NEW_DRUM || t->type() == Track::MIDI)                          return false;                    AudioTrack* track = (AudioTrack*) t; diff --git a/muse2/muse/shortcuts.cpp b/muse2/muse/shortcuts.cpp index e6260749..7563fd93 100644 --- a/muse2/muse/shortcuts.cpp +++ b/muse2/muse/shortcuts.cpp @@ -99,6 +99,7 @@ void initShortCuts()        defShrt(SHRT_OPEN_MIDI_TRANSFORM,   Qt::CTRL + Qt::Key_T, "Open midi transformer", ARRANG_SHRT, "open_midi_transform");        defShrt(SHRT_ADD_MIDI_TRACK,        Qt::CTRL + Qt::Key_J, "Add midi track", ARRANG_SHRT, "add_midi_track");        defShrt(SHRT_ADD_DRUM_TRACK,        0, "Add drum track", ARRANG_SHRT, "add_drum_track"); +      defShrt(SHRT_ADD_NEW_STYLE_DRUM_TRACK,        0, "Add new style drum track", ARRANG_SHRT, "add_new_style_drum_track");        defShrt(SHRT_ADD_WAVE_TRACK,        0, "Add wave track", ARRANG_SHRT, "add_wave_track");        defShrt(SHRT_ADD_AUDIO_OUTPUT,      0, "Add audio output", ARRANG_SHRT, "add_audio_output");        defShrt(SHRT_ADD_AUDIO_GROUP,       0, "Add audio group", ARRANG_SHRT, "add_audio_group"); diff --git a/muse2/muse/shortcuts.h b/muse2/muse/shortcuts.h index 626c4fb8..dc2e6f22 100644 --- a/muse2/muse/shortcuts.h +++ b/muse2/muse/shortcuts.h @@ -174,6 +174,7 @@ enum {        SHRT_ADD_MIDI_TRACK, //Default: Ctrl+J        SHRT_ADD_DRUM_TRACK, //Default: undefined +      SHRT_ADD_NEW_STYLE_DRUM_TRACK, //Default: undefined        SHRT_ADD_WAVE_TRACK, //Default: undefined        SHRT_ADD_AUDIO_OUTPUT, //Default: undefined        SHRT_ADD_AUDIO_GROUP, //Default: undefined diff --git a/muse2/muse/song.cpp b/muse2/muse/song.cpp index 0f19c313..c9efe288 100644 --- a/muse2/muse/song.cpp +++ b/muse2/muse/song.cpp @@ -243,6 +243,11 @@ Track* Song::addTrack(Track::TrackType type, Track* insertAt)                    track = new MidiTrack();                    track->setType(Track::MIDI);                    break; +            case Track::NEW_DRUM: +                  track = new MidiTrack(); +                  track->setType(Track::NEW_DRUM); +                  ((MidiTrack*)track)->setOutChannel(9); +                  break;              case Track::DRUM:                    track = new MidiTrack();                    track->setType(Track::DRUM); @@ -320,7 +325,7 @@ Track* Song::addTrack(Track::TrackType type, Track* insertAt)                  {                    defOutFound = true;                    mt->setOutPort(i); -                  if(type != Track::DRUM)  // p4.0.17 Leave drum tracks at channel 10. +                  if(type != Track::DRUM  &&  type != Track::NEW_DRUM)  // p4.0.17 Leave drum tracks at channel 10.                      mt->setOutChannel(ch);                    updateFlags |= SC_ROUTE;                    break;                @@ -341,6 +346,7 @@ Track* Song::addTrack(Track::TrackType type, Track* insertAt)              switch(type) {                    //case Track::MIDI:                    //case Track::DRUM: +                  //case Track::NEW_DRUM:                    //case Track::AUDIO_OUTPUT:                    //      break; @@ -440,7 +446,7 @@ bool Song::addEvent(Event& event, Part* part)              MidiPort* mp = &MusEGlobal::midiPorts[track->outPort()];              // Is it a drum controller event, according to the track port's instrument? -            if(track->type() == Track::DRUM) +            if(track->type() == Track::DRUM) //FINDMICHJETZT was ist das?              {                MidiController* mc = mp->drumController(cntrl);                if(mc) @@ -513,7 +519,7 @@ void Song::changeEvent(Event& oldEvent, Event& newEvent, Part* part)              int cntrl = oldEvent.dataA();              MidiPort* mp = &MusEGlobal::midiPorts[track->outPort()];              // Is it a drum controller event, according to the track port's instrument? -            if(track->type() == Track::DRUM) +            if(track->type() == Track::DRUM) //FINDMICHJETZT was ist das?              {                MidiController* mc = mp->drumController(cntrl);                if(mc) @@ -540,7 +546,7 @@ void Song::changeEvent(Event& oldEvent, Event& newEvent, Part* part)              int val   = newEvent.dataB();              MidiPort* mp = &MusEGlobal::midiPorts[track->outPort()];              // Is it a drum controller event, according to the track port's instrument? -            if(track->type() == Track::DRUM) +            if(track->type() == Track::DRUM) //FINDMICHJETZT was ist das?              {                MidiController* mc = mp->drumController(cntrl);                if(mc) @@ -574,7 +580,7 @@ void Song::deleteEvent(Event& event, Part* part)              MidiPort* mp = &MusEGlobal::midiPorts[track->outPort()];              // Is it a drum controller event, according to the track port's instrument? -            if(track->type() == Track::DRUM) +            if(track->type() == Track::DRUM) //FINDMICHJETZT was ist das?              {                MidiController* mc = mp->drumController(cntrl);                if(mc) @@ -615,7 +621,7 @@ void Song::remapPortDrumCtrlEvents(int mapidx, int newnote, int newchan, int new    for(ciMidiTrack it = _midis.begin(); it != _midis.end(); ++it)     {      MidiTrack* mt = *it; -    if(mt->type() != Track::DRUM) +    if(mt->type() != Track::DRUM) //FINDMICHJETZT was ist das? drumcontroller?        continue;      MidiPort* trackmp = &MusEGlobal::midiPorts[mt->outPort()]; @@ -629,6 +635,7 @@ void Song::remapPortDrumCtrlEvents(int mapidx, int newnote, int newchan, int new        {          const Event& ev = ie->second;          // Added by T356. Do not handle events which are past the end of the part. +        //FINDMICHJETZT why not?          if(ev.tick() >= len)            break; @@ -685,7 +692,7 @@ void Song::changeAllPortDrumCtrlEvents(bool add, bool drumonly)    for(ciMidiTrack it = _midis.begin(); it != _midis.end(); ++it)     {      MidiTrack* mt = *it; -    if(mt->type() != Track::DRUM) +    if(mt->type() != Track::DRUM) //FINDMICHJETZT was ist das? drumcontroller        continue;      trackmp = &MusEGlobal::midiPorts[mt->outPort()]; @@ -1473,11 +1480,13 @@ void Song::rewindStart()  //   update  //--------------------------------------------------------- -void Song::update(int flags) +void Song::update(int flags, bool allowRecursion)        {        static int level = 0;         // DEBUG -      if (level) { -            printf("Song::update %08x, level %d\n", flags, level); +      if (level && !allowRecursion) { +            printf("THIS SHOULD NEVER HAPPEN: unallowed recursion in Song::update(%08x), level %d!\n" +                   "                          the songChanged() signal is NOT emitted. this will\n" +                   "                          probably cause windows being not up-to-date.\n", flags, level);              return;              }        ++level; @@ -3354,6 +3363,7 @@ void Song::insertTrack2(Track* track, int idx)        switch(track->type()) {              case Track::MIDI:              case Track::DRUM: +            case Track::NEW_DRUM:                    _midis.push_back((MidiTrack*)track);                    // Added by T356.                    //((MidiTrack*)track)->addPortCtrlEvents(); @@ -3604,6 +3614,7 @@ void Song::removeTrack2(Track* track)        switch(track->type()) {              case Track::MIDI:              case Track::DRUM: +            case Track::NEW_DRUM:                    // Added by T356.                    //((MidiTrack*)track)->removePortCtrlEvents();                    removePortCtrlEvents(((MidiTrack*)track)); diff --git a/muse2/muse/song.h b/muse2/muse/song.h index 7bbd831d..d6d3628c 100644 --- a/muse2/muse/song.h +++ b/muse2/muse/song.h @@ -383,7 +383,9 @@ class Song : public QObject {     public slots:        void seekTo(int tick); -      void update(int flags = -1); +      void update(int flags = -1, bool allowRecursion=false); // use allowRecursion with care! this +                                                              // could lock up muse if you aren't sure +                                                              // that your recursion will be finite!        void beat();        void undo(); diff --git a/muse2/muse/songfile.cpp b/muse2/muse/songfile.cpp index 07b03c5e..9efc75bd 100644 --- a/muse2/muse/songfile.cpp +++ b/muse2/muse/songfile.cpp @@ -725,7 +725,7 @@ void Part::read(Xml& xml, int, bool toTrack)    // int newPartOffset                                              newPartOffset=this->tick();                                            int ctl = e.dataA(); -                                          if(mt->type() == Track::DRUM) +                                          if(mt->type() == Track::DRUM) //FINDMICHJETZT commented out: was ist das?                                            {                                              // Is it a drum controller event, according to the track port's instrument?                                              MidiController* mc = mp->drumController(ctl); @@ -1050,6 +1050,12 @@ void Song::read(Xml& xml, bool isTemplate)                                track->read(xml);                                insertTrack0(track, -1);                                } +                        else if (tag == "newdrumtrack") { +                              MidiTrack* track = new MidiTrack(); +                              track->setType(Track::NEW_DRUM); +                              track->read(xml); +                              insertTrack0(track, -1); +                              }                          else if (tag == "wavetrack") {                                MusECore::WaveTrack* track = new MusECore::WaveTrack();                                track->read(xml); diff --git a/muse2/muse/track.cpp b/muse2/muse/track.cpp index 6fbe81c5..e2149ddb 100644 --- a/muse2/muse/track.cpp +++ b/muse2/muse/track.cpp @@ -32,6 +32,7 @@  #include "audio.h"  #include "globaldefs.h"  #include "route.h" +#include "drummap.h"  namespace MusECore { @@ -42,8 +43,8 @@ bool Track::_tmpSoloChainDoIns   = false;  bool Track::_tmpSoloChainNoDec   = false;  const char* Track::_cname[] = { -      "Midi", "Drum", "Wave", "AudioOut", "AudioIn", "AudioGroup",  -      "AudioAux", "AudioSynth" +      "Midi", "Drum", "NewStyleDrum", "Wave", +      "AudioOut", "AudioIn", "AudioGroup", "AudioAux", "AudioSynth"        }; @@ -77,7 +78,7 @@ void addPortCtrlEvents(MidiTrack* t)          MidiPort* mp = &MusEGlobal::midiPorts[t->outPort()];          // Is it a drum controller event, according to the track port's instrument? -        if(t->type() == Track::DRUM) +        if(t->type() == Track::DRUM)  //FINDMICHJETZT was soll das? drumcontroller -_-          {            MidiController* mc = mp->drumController(cntrl);            if(mc) @@ -125,7 +126,7 @@ void removePortCtrlEvents(MidiTrack* t)          MidiPort* mp = &MusEGlobal::midiPorts[t->outPort()];          // Is it a drum controller event, according to the track port's instrument? -        if(t->type() == Track::DRUM) +        if(t->type() == Track::DRUM)  //FINDMICHJETZT was soll das? drumcontroller...          {            MidiController* mc = mp->drumController(cntrl);            if(mc) @@ -243,7 +244,8 @@ Track::Track(const Track& t, bool cloneParts)          // A couple of schemes were conceived to deal with cloneList being invalid, but the best way is          //  to not alter the part list here. It's a big headache because: Either the parts in the cloneList          //  need to be reliably looked up replaced with the new ones, or the clipboard and cloneList must be cleared. -        // Fortunately the ONLY part of muse using this function is track rename (in TrackList and TrackInfo). +        // Fortunately the ONLY parts of muse using this function are track rename (in TrackList and TrackInfo) and +        // changing track type from MIDI to NEW_DRUM or vice versa (NOT something -> DRUM or vice versa).          // So we can get away with leaving this out:           //for (iPart ip = _parts.begin(); ip != _parts.end(); ++ip)           //      ip->second->setTrack(this); @@ -315,6 +317,7 @@ void Track::setDefaultName()        switch(_type) {              case MIDI:              case DRUM: +            case NEW_DRUM:              case WAVE:                    base = QString("Track");                    break; @@ -398,6 +401,23 @@ MidiTrack::MidiTrack()        _events = new EventList;        _mpevents = new MPEventList;        clefType=trebleClef; +       +      _drummap=new DrumMap[128]; +      _drummap_hidden=new bool[128]; +       +      for (int i=0;i<128;i++) +      { +        int idx=idrumMap[i].anote; +        if (idx < 0 || idx >= 128) +          printf ("ERROR: THIS SHOULD NEVER HAPPEN: idrumMap[%i].anote is not within 0..127!\n", idx); +        else +          _drummap[idx]=idrumMap[i]; +         +        MusEGlobal::global_drum_ordering.push_back(std::pair<MidiTrack*,int>(this,idx)); +      } +      for (int i=0;i<128;i++) +        _drummap_hidden[i]=false; +        }  //MidiTrack::MidiTrack(const MidiTrack& mt) @@ -418,12 +438,36 @@ MidiTrack::MidiTrack(const MidiTrack& mt, bool cloneParts)        compression    = mt.compression;        _recEcho       = mt.recEcho();        clefType=trebleClef; + +      _drummap=new DrumMap[128]; +      _drummap_hidden=new bool[128]; +      memcpy(_drummap, mt._drummap, 128*sizeof(*_drummap)); +      memcpy(_drummap_hidden, mt._drummap_hidden, 128*sizeof(*_drummap_hidden)); +       +      for (MusEGlobal::global_drum_ordering_t::iterator it=MusEGlobal::global_drum_ordering.begin(); it!=MusEGlobal::global_drum_ordering.end(); it++) +        if (it->first == &mt) +        { +          it=MusEGlobal::global_drum_ordering.insert(it, *it); // duplicates the entry at it, set it to the first entry of both +          it++;                                                // make it point to the second entry +          it->first=this; +        }        }  MidiTrack::~MidiTrack()        {        delete _events;        delete _mpevents; +      delete [] _drummap; +      delete [] _drummap_hidden; +       +      // remove ourselves from the global_drum_ordering list +      // this is not really necessary, but cleaner +      for (MusEGlobal::global_drum_ordering_t::iterator it=MusEGlobal::global_drum_ordering.begin(); it!=MusEGlobal::global_drum_ordering.end();) +        if (it->first == this) +          it=MusEGlobal::global_drum_ordering.erase(it); +        else +          it++; +        }  //--------------------------------------------------------- @@ -433,7 +477,7 @@ MidiTrack::~MidiTrack()  void MidiTrack::init()        {        _outPort       = 0; -      _outChannel    = 0; +      _outChannel    = (type()==NEW_DRUM) ? 9 : 0;        // Changed by Tim. p3.3.8        //_inPortMask    = 0xffff;        ///_inPortMask    = 0xffffffff; @@ -607,7 +651,7 @@ void MidiTrack::addPortCtrlEvents()          MidiPort* mp = &MusEGlobal::midiPorts[_outPort];          // Is it a drum controller event, according to the track port's instrument? -        if(type() == DRUM) +        if(type() == DRUM)  //FINDMICHJETZT commented out. was soll das?          {            MidiController* mc = mp->drumController(cntrl);            if(mc) @@ -648,7 +692,7 @@ void MidiTrack::removePortCtrlEvents()          MidiPort* mp = &MusEGlobal::midiPorts[_outPort];          // Is it a drum controller event, according to the track port's instrument? -        if(type() == DRUM) +        if(type() == DRUM)  //FINDMICHJETZT commented out: was soll das?          {            MidiController* mc = mp->drumController(cntrl);            if(mc) @@ -720,8 +764,13 @@ void MidiTrack::write(int level, Xml& xml) const        if (type() == DRUM)              tag = "drumtrack"; -      else +      else if (type() == MIDI)              tag = "miditrack"; +      else if (type() == NEW_DRUM) +            tag = "newdrumtrack"; +      else +            printf("THIS SHOULD NEVER HAPPEN: non-midi-type in MidiTrack::write()\n"); +              xml.tag(level++, tag);        Track::writeProperties(level, xml); diff --git a/muse2/muse/track.h b/muse2/muse/track.h index 46dfc59f..9d3db8af 100644 --- a/muse2/muse/track.h +++ b/muse2/muse/track.h @@ -44,6 +44,7 @@ class PluginI;  class SndFile;  class SynthI;  class Xml; +class DrumMap;  //--------------------------------------------------------- @@ -53,7 +54,7 @@ class Xml;  class Track {     public:        enum TrackType { -         MIDI=0, DRUM, WAVE, AUDIO_OUTPUT, AUDIO_INPUT, AUDIO_GROUP, +         MIDI=0, DRUM, NEW_DRUM, WAVE, AUDIO_OUTPUT, AUDIO_INPUT, AUDIO_GROUP,           AUDIO_AUX, AUDIO_SOFTSYNTH           };     private: @@ -200,11 +201,11 @@ class Track {        void setDefaultName();        int channels() const                { return _channels; }        virtual void setChannels(int n); -      bool isMidiTrack() const       { return type() == MIDI || type() == DRUM; } +      bool isMidiTrack() const       { return type() == MIDI || type() == DRUM || type() == NEW_DRUM; }        virtual bool canRecord() const { return false; }        virtual AutomationType automationType() const    = 0;        virtual void setAutomationType(AutomationType t) = 0; -      static void setVisible(bool ) { } +      static void setVisible(bool) { }        }; @@ -227,6 +228,12 @@ class MidiTrack : public Track {        MPEventList* _mpevents; // tmp Events druring recording        static bool _isVisible;        clefTypes clefType; +       +      DrumMap* _drummap; +      bool _drummap_tied_to_patch; //if true, changing patch also changes drummap +      bool* _drummap_hidden; + +      void init();     public:        MidiTrack(); @@ -234,7 +241,6 @@ class MidiTrack : public Track {        MidiTrack(const MidiTrack&, bool cloneParts);        virtual ~MidiTrack(); -      void init();        virtual AutomationType automationType() const;        virtual void setAutomationType(AutomationType); @@ -295,6 +301,9 @@ class MidiTrack : public Track {        void setClef(clefTypes i) { clefType = i; }        clefTypes getClef() { return clefType; } +       +      DrumMap* drummap() { return _drummap; } +      bool* drummap_hidden() { return _drummap_hidden; }        };  } // namespace MusECore diff --git a/muse2/muse/undo.cpp b/muse2/muse/undo.cpp index eb554495..5bbcfcd8 100644 --- a/muse2/muse/undo.cpp +++ b/muse2/muse/undo.cpp @@ -777,6 +777,7 @@ void Song::doRedo2()  UndoOp::UndoOp()  { +  type=UndoOp::DoNothing;  }  UndoOp::UndoOp(UndoType type_) @@ -1075,4 +1076,16 @@ void Song::doRedo3()        dirty = true;        } + +bool Undo::empty() const +{ +  if (std::list<UndoOp>::empty()) return true; +   +  for (const_iterator it=begin(); it!=end(); it++) +    if (it->type!=UndoOp::DoNothing) +      return false; +   +  return true; +} +  } // namespace MusECore diff --git a/muse2/muse/undo.h b/muse2/muse/undo.h index 19c252bf..42a80763 100644 --- a/muse2/muse/undo.h +++ b/muse2/muse/undo.h @@ -121,7 +121,8 @@ struct UndoOp {        };  class Undo : public std::list<UndoOp> { -      void undoOp(UndoOp::UndoType, int data); +   public: +      bool empty() const;        };  typedef Undo::iterator iUndoOp; diff --git a/muse2/muse/widgets/mtrackinfo.cpp b/muse2/muse/widgets/mtrackinfo.cpp index b5460447..33462d0c 100644 --- a/muse2/muse/widgets/mtrackinfo.cpp +++ b/muse2/muse/widgets/mtrackinfo.cpp @@ -216,6 +216,7 @@ void MidiTrackInfo::heartBeat()    {      case MusECore::Track::MIDI:      case MusECore::Track::DRUM: +    case MusECore::Track::NEW_DRUM:      {        MusECore::MidiTrack* track = (MusECore::MidiTrack*)selected; @@ -344,7 +345,7 @@ void MidiTrackInfo::heartBeat()          else          {            MusECore::MidiInstrument* instr = mp->instrument(); -          QString name = instr->getPatchName(outChannel, nprogram, MusEGlobal::song->mtype(), track->type() == MusECore::Track::DRUM); +          QString name = instr->getPatchName(outChannel, nprogram, MusEGlobal::song->mtype(), track->type() == MusECore::Track::DRUM); //FINDMICHJETZT was soll das?            if(name.isEmpty())            {              const QString n("???"); @@ -390,7 +391,7 @@ void MidiTrackInfo::heartBeat()                //else                 //{                      MusECore::MidiInstrument* instr = mp->instrument(); -                    QString name = instr->getPatchName(outChannel, program, MusEGlobal::song->mtype(), track->type() == MusECore::Track::DRUM); +                    QString name = instr->getPatchName(outChannel, program, MusEGlobal::song->mtype(), track->type() == MusECore::Track::DRUM);  //FINDMICHJETZT was soll das?                      if(iPatch->text() != name)                        iPatch->setText(name); @@ -567,8 +568,12 @@ void MidiTrackInfo::setLabelText()          //pal.setColor(trackNameLabel->backgroundRole(), QColor(0, 160, 255)); // Med blue          if(track->type() == MusECore::Track::DRUM)            c = MusEGlobal::config.drumTrackLabelBg;  -        else   +        else if (track->type() == MusECore::Track::MIDI)            c = MusEGlobal::config.midiTrackLabelBg;  +        else if (track->type() == MusECore::Track::NEW_DRUM) +          c = MusEGlobal::config.newDrumTrackLabelBg; +        else +          printf("THIS SHOULD NEVER HAPPEN: track is not a MIDI track in MidiTrackInfo::setLabelText()!\n");          QLinearGradient gradient(trackNameLabel->geometry().topLeft(), trackNameLabel->geometry().bottomLeft());          //gradient.setColorAt(0, c.darker()); @@ -757,7 +762,7 @@ void MidiTrackInfo::iProgHBankChanged()        MusEGlobal::audio->msgPlayMidiEvent(&ev);        MusECore::MidiInstrument* instr = mp->instrument(); -      iPatch->setText(instr->getPatchName(channel, program, MusEGlobal::song->mtype(), track->type() == MusECore::Track::DRUM)); +      iPatch->setText(instr->getPatchName(channel, program, MusEGlobal::song->mtype(), track->type() == MusECore::Track::DRUM));  //FINDMICHJETZT was soll das?  //      updateTrackInfo();        } @@ -835,7 +840,7 @@ void MidiTrackInfo::iProgLBankChanged()        MusEGlobal::audio->msgPlayMidiEvent(&ev);        MusECore::MidiInstrument* instr = mp->instrument(); -      iPatch->setText(instr->getPatchName(channel, program, MusEGlobal::song->mtype(), track->type() == MusECore::Track::DRUM)); +      iPatch->setText(instr->getPatchName(channel, program, MusEGlobal::song->mtype(), track->type() == MusECore::Track::DRUM)); //FINDMICHJETZT was soll das?  //      updateTrackInfo();        } @@ -913,7 +918,7 @@ void MidiTrackInfo::iProgramChanged()          MusEGlobal::audio->msgPlayMidiEvent(&ev);          MusECore::MidiInstrument* instr = mp->instrument(); -        iPatch->setText(instr->getPatchName(channel, program, MusEGlobal::song->mtype(), track->type() == MusECore::Track::DRUM)); +        iPatch->setText(instr->getPatchName(channel, program, MusEGlobal::song->mtype(), track->type() == MusECore::Track::DRUM)); //FINDMICHJETZT was soll das?        }  //      updateTrackInfo(); @@ -1082,7 +1087,7 @@ void MidiTrackInfo::instrPopup()        PopupMenu* pup = new PopupMenu(true);        //instr->populatePatchPopup(pop, channel, MusEGlobal::song->mtype(), track->type() == MusECore::Track::DRUM); -      populatePatchPopup(instr, pup, channel, MusEGlobal::song->mtype(), track->type() == MusECore::Track::DRUM); +      populatePatchPopup(instr, pup, channel, MusEGlobal::song->mtype(), track->type() == MusECore::Track::DRUM); //FINDMICHJETZT was soll das?        //if(pop->actions().count() == 0)        //  return; @@ -1406,7 +1411,7 @@ void MidiTrackInfo::updateTrackInfo(int flags)            else            {              MusECore::MidiInstrument* instr = mp->instrument(); -            iPatch->setText(instr->getPatchName(outChannel, nprogram, MusEGlobal::song->mtype(), track->type() == MusECore::Track::DRUM)); +            iPatch->setText(instr->getPatchName(outChannel, nprogram, MusEGlobal::song->mtype(), track->type() == MusECore::Track::DRUM)); //FINDMICHJETZT was soll das?            }                   }          else @@ -1422,7 +1427,7 @@ void MidiTrackInfo::updateTrackInfo(int flags)                //else                 //{                      MusECore::MidiInstrument* instr = mp->instrument(); -                    iPatch->setText(instr->getPatchName(outChannel, program, MusEGlobal::song->mtype(), track->type() == MusECore::Track::DRUM)); +                    iPatch->setText(instr->getPatchName(outChannel, program, MusEGlobal::song->mtype(), track->type() == MusECore::Track::DRUM)); //FINDMICHJETZT was soll das?                      int hb = ((program >> 16) & 0xff) + 1;                      if (hb == 0x100) diff --git a/muse2/muse/widgets/musewidgetsplug.cpp b/muse2/muse/widgets/musewidgetsplug.cpp index 8520a731..26a3054d 100644 --- a/muse2/muse/widgets/musewidgetsplug.cpp +++ b/muse2/muse/widgets/musewidgetsplug.cpp @@ -131,6 +131,7 @@ GlobalConfigValues config = {        QColor(0, 160, 255),          // midiTrackLabelBg;   // Med blue        QColor(0, 160, 255),          // drumTrackLabelBg;   // Med blue +      QColor(0, 160, 255),          // newDrumTrackLabelBg;   // Med blue        Qt::magenta,                  // waveTrackLabelBg;        Qt::green,                    // outputTrackLabelBg;        Qt::red,                      // inputTrackLabelBg; @@ -140,6 +141,7 @@ GlobalConfigValues config = {        QColor(220, 220, 220),     // midiTrackBg;        QColor(220, 220, 220),     // drumTrackBg; +      QColor(220, 220, 220),     // newDrumTrackBg;        QColor(220, 220, 220),     // waveTrackBg;        QColor(189, 220, 193),     // outputTrackBg;        QColor(189, 220, 193),     // inputTrackBg; @@ -178,13 +180,13 @@ GlobalConfigValues config = {           QString("Mixer A"),           QRect(0, 0, 300, 500),        // Mixer1           true, true, true, true, -         true, true, true, true +         true, true, true, true, true           },        {           QString("Mixer B"),           QRect(200, 200, 300, 500),    // Mixer2           true, true, true, true, -         true, true, true, true +         true, true, true, true, true           },        true,                         // TransportVisible;        false,                        // BigTimeVisible; diff --git a/muse2/xpm/eye.xpm b/muse2/xpm/eye.xpm new file mode 100644 index 00000000..74e5bcc1 --- /dev/null +++ b/muse2/xpm/eye.xpm @@ -0,0 +1,22 @@ +/* XPM */ +static const char * eye_xpm[] = { +"16 16 3 1", +" 	c None", +".	c #000000", +"+	c #0000FD", +"                ", +"                ", +"                ", +"      ....      ", +"    ........    ", +"  ...      ...  ", +" ...  ++++  ... ", +"...  ++++++  ...", +"..   ++++++   ..", +"...  ++++++  ...", +" ...  ++++  ... ", +"  ...      ...  ", +"    ........    ", +"      ....      ", +"                ", +"                "}; diff --git a/muse2/xpm/eye_crossed.xpm b/muse2/xpm/eye_crossed.xpm new file mode 100644 index 00000000..65dca19c --- /dev/null +++ b/muse2/xpm/eye_crossed.xpm @@ -0,0 +1,23 @@ +/* XPM */ +static const char * eye_crossed_xpm[] = { +"16 16 4 1", +" 	c None", +".	c #E10E08", +"+	c #000000", +"@	c #0000FD", +"                ", +"             .. ", +"            ....", +"      ++++ .... ", +"    ++++++....  ", +"  +++    ....+  ", +" +++  @@....+++ ", +"+++  @@....  +++", +"++   @....@   ++", +"+++  ....@@  +++", +" +++....@@  +++ ", +"  +....    +++  ", +"  ....++++++    ", +" .... ++++      ", +"  ..            ", +"                "}; diff --git a/muse2/xpm/eye_gray.xpm b/muse2/xpm/eye_gray.xpm new file mode 100644 index 00000000..8d5a7d9d --- /dev/null +++ b/muse2/xpm/eye_gray.xpm @@ -0,0 +1,22 @@ +/* XPM */ +static const char * eye_gray_xpm[] = { +"16 16 3 1", +" 	c None", +".	c #292929", +"+	c #535353", +"                ", +"                ", +"                ", +"      ....      ", +"    ........    ", +"  ...      ...  ", +" ...  ++++  ... ", +"...  ++++++  ...", +"..   ++++++   ..", +"...  ++++++  ...", +" ...  ++++  ... ", +"  ...      ...  ", +"    ........    ", +"      ....      ", +"                ", +"                "};  | 
