PlaybackScreen.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. #include "Sequencer.h"
  2. #include "PlaybackScreen.h"
  3. #include "colors.h"
  4. #include <iostream>
  5. PlaybackScreen::PlaybackScreen(Sequencer& seq)
  6. : parent(seq), beatDisplayOffset(0)
  7. {
  8. }
  9. void PlaybackScreen::enable()
  10. {
  11. if(sequencer.beats.size() == 0) {
  12. beatDisplayOffset = 0;
  13. } else {
  14. beatDisplayOffset = std::min(
  15. beatDisplayOffset,
  16. (Player::BeatIndex)(sequencer.beats.size() - 1) / beatDisplayWidth * beatDisplayWidth
  17. );
  18. }
  19. refreshAll();
  20. parent::enable();
  21. }
  22. void PlaybackScreen::beforeBeat(Player::BeatIndex beat)
  23. {
  24. // std::cout << "before beat #" << beat << std::endl;
  25. beatDisplayOffset = beat / beatDisplayWidth * beatDisplayWidth;
  26. refreshAll();
  27. }
  28. void PlaybackScreen::afterBeat(Player::BeatIndex beat)
  29. {
  30. }
  31. void PlaybackScreen::keyPressed(unsigned char x, unsigned char y)
  32. {
  33. // std::cout << "clicked x=" << (int)x << ", y=" << (int)y << std::endl;
  34. if(x == 8) { // very right
  35. if(y < sequencer.messages.size()) {
  36. std::shared_ptr<midi::Message> msg_ptr = sequencer.messages[y];
  37. msg_ptr->print(std::cout);
  38. sequencer.midiOut.sendMessage(*msg_ptr);
  39. }
  40. } else if(y == 8) { // very top
  41. bool playing = sequencer.player.isPlaying();
  42. switch(x) {
  43. case 2: // left
  44. if(!playing && beatDisplayOffset > 0) {
  45. beatDisplayOffset = std::max((Player::BeatIndex)0, beatDisplayOffset - beatDisplayWidth);
  46. }
  47. break;
  48. case 3: // right
  49. if(!playing && (beatDisplayOffset + beatDisplayWidth) < sequencer.beats.size()) {
  50. beatDisplayOffset += beatDisplayWidth;
  51. }
  52. break;
  53. case 5:
  54. disable();
  55. sequencer.configScreen.enable();
  56. break;
  57. case 7: // start / stop
  58. if(playing) {
  59. sequencer.player.stop();
  60. } else {
  61. sequencer.player.loop();
  62. }
  63. break;
  64. }
  65. } else {
  66. Player::BeatIndex beatIndex = x + beatDisplayOffset;
  67. if(beatIndex < sequencer.beats.size() && y < sequencer.messages.size()) {
  68. std::shared_ptr<midi::NoteOnMessage> noteOnMessage_ptr
  69. = std::dynamic_pointer_cast<midi::NoteOnMessage>(sequencer.messages[y]);
  70. if(noteOnMessage_ptr) {
  71. toggleOnMessage(noteOnMessage_ptr, beatIndex);
  72. }
  73. }
  74. }
  75. refreshAll();
  76. }
  77. void PlaybackScreen::keyReleased(unsigned char x, unsigned char y)
  78. {
  79. refreshAll();
  80. }
  81. void PlaybackScreen::refresh(unsigned char x, unsigned char y)
  82. {
  83. if(x == 8) { // very right
  84. if(y < sequencer.messages.size()) {
  85. setColor(x, y, getKeyPressed(x, y) ? colors::activeOption : colors::inactiveOption);
  86. } else {
  87. setColor(x, y, colors::dark);
  88. }
  89. } else if(y == 8) { // very top
  90. bool playing = sequencer.player.isPlaying();
  91. switch(x) {
  92. case 2: // left
  93. if(!playing && beatDisplayOffset > 0) {
  94. setColor(x, y, colors::inactiveOption);
  95. } else {
  96. setColor(x, y, colors::dark);
  97. }
  98. break;
  99. case 3: // right
  100. if(!playing && (beatDisplayOffset + beatDisplayWidth) < sequencer.beats.size()) {
  101. setColor(x, y, colors::inactiveOption);
  102. } else {
  103. setColor(x, y, colors::dark);
  104. }
  105. break;
  106. case 5:
  107. setColor(x, y, colors::inactiveOption);
  108. break;
  109. case 7: // start / stop
  110. if(playing) {
  111. setColor(x, y, colors::activeOption);
  112. } else {
  113. setColor(x, y, colors::inactiveOption);
  114. }
  115. break;
  116. }
  117. } else {
  118. Player::BeatIndex beatIndex = x + beatDisplayOffset;
  119. if(beatIndex < sequencer.beats.size() && y < sequencer.messages.size()) {
  120. const midi::MessageList& beat = sequencer.beats[beatIndex];
  121. std::shared_ptr<midi::Message> msg_ptr = sequencer.messages[y];
  122. if(beat.contains(*msg_ptr)) {
  123. if(sequencer.player.getNextBeat() == beatIndex) {
  124. setColor(x, y, colors::activeMessage);
  125. } else {
  126. setColor(x, y, colors::inactiveMessage);
  127. }
  128. } else {
  129. setColor(x, y, colors::dark);
  130. }
  131. } else {
  132. setColor(x, y, colors::dark);
  133. }
  134. }
  135. }
  136. void PlaybackScreen::toggleOnMessage(std::shared_ptr<midi::NoteOnMessage> noteOnMessage_ptr, Player::BeatIndex beatIndex)
  137. {
  138. noteOnMessage_ptr->print(std::cout);
  139. const midi::MessageList& beat = sequencer.beats[beatIndex];
  140. midi::MessageList::const_iterator beat_msg_it = beat.find(*noteOnMessage_ptr);
  141. if(beat_msg_it == beat.end()) {
  142. // insert message at beat
  143. sequencer.beats.pushBackMessage(beatIndex, std::dynamic_pointer_cast<midi::Message>(noteOnMessage_ptr));
  144. } else {
  145. // remove message from beat
  146. sequencer.beats.eraseMessage(beatIndex, beat_msg_it);
  147. }
  148. sequencer.beats.printRegistry(std::cout);
  149. }