comparison main/MainWindow.cpp @ 308:4ad11b1cf050

* Handle zero-velocity note ons as well as note offs (can't believe I fell for that one) * Add Peek Left / Peek Right (alt+left/right) and change peek-drag (i.e. dragging without moving playback pointer or other panes) from ctrl+drag to alt+drag for symmetry
author Chris Cannam
date Thu, 26 Feb 2009 10:49:08 +0000
parents d4ff14feca76
children 6a276fea550d
comparison
equal deleted inserted replaced
307:d4ff14feca76 308:4ad11b1cf050
702 702
703 action = new QAction(tr("J&ump Right"), this); 703 action = new QAction(tr("J&ump Right"), this);
704 action->setShortcut(tr("Ctrl+Right")); 704 action->setShortcut(tr("Ctrl+Right"));
705 action->setStatusTip(tr("Scroll the current pane a big step to the right")); 705 action->setStatusTip(tr("Scroll the current pane a big step to the right"));
706 connect(action, SIGNAL(triggered()), this, SLOT(jumpRight())); 706 connect(action, SIGNAL(triggered()), this, SLOT(jumpRight()));
707 connect(this, SIGNAL(canScroll(bool)), action, SLOT(setEnabled(bool)));
708 m_keyReference->registerShortcut(action);
709 menu->addAction(action);
710
711 action = new QAction(tr("Peek Left"), this);
712 action->setShortcut(tr("Alt+Left"));
713 action->setStatusTip(tr("Scroll the current pane to the left without moving the playback cursor or other panes"));
714 connect(action, SIGNAL(triggered()), this, SLOT(peekLeft()));
715 connect(this, SIGNAL(canScroll(bool)), action, SLOT(setEnabled(bool)));
716 m_keyReference->registerShortcut(action);
717 menu->addAction(action);
718
719 action = new QAction(tr("Peek Right"), this);
720 action->setShortcut(tr("Alt+Right"));
721 action->setStatusTip(tr("Scroll the current pane to the right without moving the playback cursor or other panes"));
722 connect(action, SIGNAL(triggered()), this, SLOT(peekRight()));
707 connect(this, SIGNAL(canScroll(bool)), action, SLOT(setEnabled(bool))); 723 connect(this, SIGNAL(canScroll(bool)), action, SLOT(setEnabled(bool)));
708 m_keyReference->registerShortcut(action); 724 m_keyReference->registerShortcut(action);
709 menu->addAction(action); 725 menu->addAction(action);
710 726
711 menu->addSeparator(); 727 menu->addSeparator();
3426 // (across threads). It could happen quite some time after the 3442 // (across threads). It could happen quite some time after the
3427 // event was actually received, which is why event timestamping 3443 // event was actually received, which is why event timestamping
3428 // happens in the MIDI input class and not here. 3444 // happens in the MIDI input class and not here.
3429 3445
3430 while (m_midiInput->getEventsAvailable() > 0) { 3446 while (m_midiInput->getEventsAvailable() > 0) {
3447
3431 MIDIEvent ev(m_midiInput->readEvent()); 3448 MIDIEvent ev(m_midiInput->readEvent());
3432 3449
3450 bool noteOn = (ev.getMessageType() == MIDIConstants::MIDI_NOTE_ON &&
3451 ev.getVelocity() > 0);
3452
3453 bool noteOff = (ev.getMessageType() == MIDIConstants::MIDI_NOTE_OFF ||
3454 (ev.getMessageType() == MIDIConstants::MIDI_NOTE_ON &&
3455 ev.getVelocity() == 0));
3456
3433 if (currentNoteLayer) { 3457 if (currentNoteLayer) {
3434 3458
3435 if (ev.getMessageType() == MIDIConstants::MIDI_NOTE_ON) { 3459 if (noteOn) {
3436 3460
3437 currentNoteLayer->addNoteOn(ev.getTime(), 3461 currentNoteLayer->addNoteOn(ev.getTime(),
3438 ev.getPitch(), 3462 ev.getPitch(),
3439 ev.getVelocity()); 3463 ev.getVelocity());
3440 3464
3441 } else if (ev.getMessageType() == MIDIConstants::MIDI_NOTE_OFF) { 3465 } else if (noteOff) {
3442 3466
3443 currentNoteLayer->addNoteOff(ev.getTime(), 3467 currentNoteLayer->addNoteOff(ev.getTime(),
3444 ev.getPitch()); 3468 ev.getPitch());
3445 3469
3446 } 3470 }
3447 3471
3448 } else { 3472 } else {
3449 if (ev.getMessageType() != MIDIConstants::MIDI_NOTE_ON) { 3473
3450 continue; 3474 if (!noteOn) continue;
3451 }
3452 insertInstantAt(ev.getTime()); 3475 insertInstantAt(ev.getTime());
3453 } 3476 }
3454 } 3477 }
3455 } 3478 }
3456 3479