|
@@ -5,7 +5,7 @@
|
|
|
#include <cassert>
|
|
|
|
|
|
PlaybackScreen::PlaybackScreen(Sequencer& seq)
|
|
|
- : parent(seq), beatDisplayOffset(0)
|
|
|
+ : parent(seq), beatDisplayOffset(0), messageDisplayOffset(0)
|
|
|
{
|
|
|
}
|
|
|
|
|
@@ -19,6 +19,9 @@ void PlaybackScreen::enable()
|
|
|
(Player::BeatIndex)(sequencer.beats.size() - 1) / beatDisplayWidth * beatDisplayWidth
|
|
|
);
|
|
|
}
|
|
|
+ if(messageDisplayOffset >= sequencer.messages.size()) {
|
|
|
+ messageDisplayOffset = sequencer.messages.size() - 1;
|
|
|
+ }
|
|
|
refreshAll();
|
|
|
parent::enable();
|
|
|
}
|
|
@@ -39,17 +42,33 @@ void PlaybackScreen::keyPressed(unsigned char x, unsigned char y)
|
|
|
// std::cout << "clicked x=" << (int)x << ", y=" << (int)y << std::endl;
|
|
|
|
|
|
if(x == 8) { // very right
|
|
|
- if(y < sequencer.messages.size()) {
|
|
|
- std::shared_ptr<midi::Message> msg_ptr = sequencer.messages[y];
|
|
|
+ std::size_t messageIndex = y + messageDisplayOffset;
|
|
|
+ if(messageIndex < sequencer.messages.size()) {
|
|
|
+ std::shared_ptr<midi::Message> msg_ptr = sequencer.messages[messageIndex];
|
|
|
msg_ptr->print(std::cout);
|
|
|
sequencer.midiOut.sendMessage(*msg_ptr);
|
|
|
}
|
|
|
} else if(y == 8) { // very top
|
|
|
bool playing = sequencer.player.isPlaying();
|
|
|
switch(x) {
|
|
|
+ case 0: // down
|
|
|
+ if(messageDisplayOffset > 0) {
|
|
|
+ int offset = messageDisplayOffset;
|
|
|
+ offset -= messageDisplayShift;
|
|
|
+ messageDisplayOffset = std::max(0, offset);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 1: // up
|
|
|
+ if(messageDisplayOffset + beatsHeight < sequencer.messages.size()) {
|
|
|
+ messageDisplayOffset = std::min(
|
|
|
+ (MessageDisplayOffset)sequencer.messages.size() - 1,
|
|
|
+ messageDisplayOffset + messageDisplayShift
|
|
|
+ );
|
|
|
+ }
|
|
|
+ break;
|
|
|
case 2: // left
|
|
|
if(!playing && beatDisplayOffset > 0) {
|
|
|
- beatDisplayOffset = std::max((Player::BeatIndex)0, beatDisplayOffset - beatDisplayWidth);
|
|
|
+ beatDisplayOffset = std::max(0, (int)beatDisplayOffset - beatDisplayWidth);
|
|
|
}
|
|
|
break;
|
|
|
case 3: // right
|
|
@@ -70,10 +89,11 @@ void PlaybackScreen::keyPressed(unsigned char x, unsigned char y)
|
|
|
break;
|
|
|
}
|
|
|
} else {
|
|
|
+ std::size_t messageIndex = y + messageDisplayOffset;
|
|
|
Player::BeatIndex beatIndex = x + beatDisplayOffset;
|
|
|
- if(beatIndex < sequencer.beats.size() && y < sequencer.messages.size()) {
|
|
|
+ if(beatIndex < sequencer.beats.size() && messageIndex < sequencer.messages.size()) {
|
|
|
std::shared_ptr<midi::NoteOnMessage> noteOnMessage_ptr
|
|
|
- = std::dynamic_pointer_cast<midi::NoteOnMessage>(sequencer.messages[y]);
|
|
|
+ = std::dynamic_pointer_cast<midi::NoteOnMessage>(sequencer.messages[messageIndex]);
|
|
|
if(noteOnMessage_ptr) {
|
|
|
toggleOnMessage(noteOnMessage_ptr, beatIndex);
|
|
|
}
|
|
@@ -86,9 +106,11 @@ void PlaybackScreen::keyPressed(unsigned char x, unsigned char y)
|
|
|
void PlaybackScreen::keyReleased(unsigned char x, unsigned char y)
|
|
|
{
|
|
|
if(x == 8) { // very right
|
|
|
- if(y < sequencer.messages.size()) {
|
|
|
+ // this might not be the right message
|
|
|
+ std::size_t messageIndex = y + messageDisplayOffset;
|
|
|
+ if(messageIndex < sequencer.messages.size()) {
|
|
|
std::shared_ptr<midi::NoteOnMessage> msgOn_ptr
|
|
|
- = std::dynamic_pointer_cast<midi::NoteOnMessage>(sequencer.messages[y]);
|
|
|
+ = std::dynamic_pointer_cast<midi::NoteOnMessage>(sequencer.messages[messageIndex]);
|
|
|
if(msgOn_ptr) {
|
|
|
sequencer.midiOut.sendMessage(msgOn_ptr->toOffMessage(0));
|
|
|
}
|
|
@@ -101,7 +123,8 @@ void PlaybackScreen::keyReleased(unsigned char x, unsigned char y)
|
|
|
void PlaybackScreen::refresh(unsigned char x, unsigned char y)
|
|
|
{
|
|
|
if(x == 8) { // very right
|
|
|
- if(y < sequencer.messages.size()) {
|
|
|
+ std::size_t messageIndex = y + messageDisplayOffset;
|
|
|
+ if(messageIndex < sequencer.messages.size()) {
|
|
|
setColor(x, y, getKeyPressed(x, y) ? colors::activeOption : colors::inactiveOption);
|
|
|
} else {
|
|
|
setColor(x, y, colors::dark);
|
|
@@ -109,6 +132,20 @@ void PlaybackScreen::refresh(unsigned char x, unsigned char y)
|
|
|
} else if(y == 8) { // very top
|
|
|
bool playing = sequencer.player.isPlaying();
|
|
|
switch(x) {
|
|
|
+ case 0: // down
|
|
|
+ if(messageDisplayOffset > 0) {
|
|
|
+ setColor(x, y, colors::inactiveOption);
|
|
|
+ } else {
|
|
|
+ setColor(x, y, colors::dark);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 1: // up
|
|
|
+ if(messageDisplayOffset + beatsHeight < sequencer.messages.size()) {
|
|
|
+ setColor(x, y, colors::inactiveOption);
|
|
|
+ } else {
|
|
|
+ setColor(x, y, colors::dark);
|
|
|
+ }
|
|
|
+ break;
|
|
|
case 2: // left
|
|
|
if(!playing && beatDisplayOffset > 0) {
|
|
|
setColor(x, y, colors::inactiveOption);
|
|
@@ -135,10 +172,11 @@ void PlaybackScreen::refresh(unsigned char x, unsigned char y)
|
|
|
break;
|
|
|
}
|
|
|
} else {
|
|
|
+ std::size_t messageIndex = y + messageDisplayOffset;
|
|
|
Player::BeatIndex beatIndex = x + beatDisplayOffset;
|
|
|
- if(beatIndex < sequencer.beats.size() && y < sequencer.messages.size()) {
|
|
|
+ if(beatIndex < sequencer.beats.size() && messageIndex < sequencer.messages.size()) {
|
|
|
std::shared_ptr<midi::NoteOnMessage> noteOnMessage_ptr
|
|
|
- = std::dynamic_pointer_cast<midi::NoteOnMessage>(sequencer.messages[y]);
|
|
|
+ = std::dynamic_pointer_cast<midi::NoteOnMessage>(sequencer.messages[messageIndex]);
|
|
|
if(noteOnMessage_ptr) {
|
|
|
setColor(x, y, getBeatColor(noteOnMessage_ptr, beatIndex));
|
|
|
}
|